perf: Query-service Performance Improvements (traces) (#838)

*feat: Update query-service Go version to 1.17 #911
*chore: Upgrade to clickhouse versions v2 #751
*feat: Duration sorting in events table of Trace-filter page #826
*feat: Add grpc status code to traces view #975
*feat: added filtering by resource attributes #881
This commit is contained in:
Vishal Sharma 2022-05-03 11:20:57 +05:30 committed by GitHub
parent 3ab4f71aa1
commit 642ece288e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
46 changed files with 1409 additions and 6479 deletions

View File

@ -33,6 +33,9 @@ services:
- --queryService.url=http://query-service:8080
- --storage.path=/data
# Notes for Maintainers/Contributors who will change Line Numbers of Frontend & Query-Section. Please Update Line Numbers in `./scripts/commentLinesForSetup.sh` & `./CONTRIBUTING.md`
query-service:
image: signoz/query-service:0.7.5
container_name: query-service
@ -42,7 +45,7 @@ services:
- ../dashboards:/root/config/dashboards
- ./data/signoz/:/var/lib/signoz/
environment:
- ClickHouseUrl=tcp://clickhouse:9000
- ClickHouseUrl=tcp://clickhouse:9000/?database=signoz_traces
- STORAGE=clickhouse
- GODEBUG=netdns=go
- TELEMETRY_ENABLED=true
@ -71,7 +74,7 @@ services:
- ../common/nginx-config.conf:/etc/nginx/conf.d/default.conf
otel-collector:
image: signoz/otelcontribcol:0.43.0
image: signoz/otelcontribcol:trace-optimized-v1
command: ["--config=/etc/otel-collector-config.yaml"]
volumes:
- ./otel-collector-config.yaml:/etc/otel-collector-config.yaml
@ -92,7 +95,7 @@ services:
condition: service_healthy
otel-collector-metrics:
image: signoz/otelcontribcol:0.43.0
image: signoz/otelcontribcol:trace-optimized-v1
command: ["--config=/etc/otel-collector-metrics-config.yaml"]
volumes:
- ./otel-collector-metrics-config.yaml:/etc/otel-collector-metrics-config.yaml
@ -112,17 +115,17 @@ services:
environment:
- JAEGER_ENDPOINT=http://otel-collector:14268/api/traces
load-hotrod:
image: "grubykarol/locust:1.2.3-python3.9-alpine3.12"
container_name: load-hotrod
hostname: load-hotrod
environment:
ATTACKED_HOST: http://hotrod:8080
LOCUST_MODE: standalone
NO_PROXY: standalone
TASK_DELAY_FROM: 5
TASK_DELAY_TO: 30
QUIET_MODE: "${QUIET_MODE:-false}"
LOCUST_OPTS: "--headless -u 10 -r 1"
volumes:
- ../common/locust-scripts:/locust
# load-hotrod:
# image: "grubykarol/locust:1.2.3-python3.9-alpine3.12"
# container_name: load-hotrod
# hostname: load-hotrod
# environment:
# ATTACKED_HOST: http://hotrod:8080
# LOCUST_MODE: standalone
# NO_PROXY: standalone
# TASK_DELAY_FROM: 5
# TASK_DELAY_TO: 30
# QUIET_MODE: "${QUIET_MODE:-false}"
# LOCUST_OPTS: "--headless -u 10 -r 1"
# volumes:
# - ../common/locust-scripts:/locust

View File

@ -44,7 +44,7 @@ services:
- ../dashboards:/root/config/dashboards
- ./data/signoz/:/var/lib/signoz/
environment:
- ClickHouseUrl=tcp://clickhouse:9000
- ClickHouseUrl=tcp://clickhouse:9000/?database=signoz_traces
- STORAGE=clickhouse
- GODEBUG=netdns=go
- TELEMETRY_ENABLED=true
@ -72,7 +72,7 @@ services:
- ../common/nginx-config.conf:/etc/nginx/conf.d/default.conf
otel-collector:
image: signoz/otelcontribcol:0.43.0
image: signoz/otelcontribcol:trace-optimized-v1
command: ["--config=/etc/otel-collector-config.yaml"]
volumes:
- ./otel-collector-config.yaml:/etc/otel-collector-config.yaml
@ -93,7 +93,7 @@ services:
condition: service_healthy
otel-collector-metrics:
image: signoz/otelcontribcol:0.43.0
image: signoz/otelcontribcol:trace-optimized-v1
command: ["--config=/etc/otel-collector-metrics-config.yaml"]
volumes:
- ./otel-collector-metrics-config.yaml:/etc/otel-collector-metrics-config.yaml
@ -102,28 +102,28 @@ services:
clickhouse:
condition: service_healthy
hotrod:
image: jaegertracing/example-hotrod:1.30
container_name: hotrod
logging:
options:
max-size: 50m
max-file: "3"
command: ["all"]
environment:
- JAEGER_ENDPOINT=http://otel-collector:14268/api/traces
# hotrod:
# image: jaegertracing/example-hotrod:1.30
# container_name: hotrod
# logging:
# options:
# max-size: 50m
# max-file: "3"
# command: ["all"]
# environment:
# - JAEGER_ENDPOINT=http://otel-collector:14268/api/traces
load-hotrod:
image: "grubykarol/locust:1.2.3-python3.9-alpine3.12"
container_name: load-hotrod
hostname: load-hotrod
environment:
ATTACKED_HOST: http://hotrod:8080
LOCUST_MODE: standalone
NO_PROXY: standalone
TASK_DELAY_FROM: 5
TASK_DELAY_TO: 30
QUIET_MODE: "${QUIET_MODE:-false}"
LOCUST_OPTS: "--headless -u 10 -r 1"
volumes:
- ../common/locust-scripts:/locust
# load-hotrod:
# image: "grubykarol/locust:1.2.3-python3.9-alpine3.12"
# container_name: load-hotrod
# hostname: load-hotrod
# environment:
# ATTACKED_HOST: http://hotrod:8080
# LOCUST_MODE: standalone
# NO_PROXY: standalone
# TASK_DELAY_FROM: 5
# TASK_DELAY_TO: 30
# QUIET_MODE: "${QUIET_MODE:-false}"
# LOCUST_OPTS: "--headless -u 10 -r 1"
# volumes:
# - ../common/locust-scripts:/locust

View File

@ -48,7 +48,7 @@ extensions:
zpages: {}
exporters:
clickhouse:
datasource: tcp://clickhouse:9000
datasource: tcp://clickhouse:9000/?database=signoz_traces
clickhousemetricswrite:
endpoint: tcp://clickhouse:9000/?database=signoz_metrics
resource_to_telemetry_conversion:

View File

@ -1,36 +0,0 @@
FROM golang:1.14-buster AS builder
# Add Maintainer Info
LABEL maintainer="signoz"
ARG TARGETPLATFORM
ENV CGO_ENABLED=0
ENV GOPATH=/go
RUN export GOOS=$(echo ${TARGETPLATFORM} | cut -d / -f1) && \
export GOARCH=$(echo ${TARGETPLATFORM} | cut -d / -f2)
# Prepare and enter src directory
WORKDIR /go/src/github.com/signoz/signoz/pkg/processors/flattener
# Cache dependencies
ADD go.mod .
ADD go.sum .
RUN go mod download -x
# Add the sources and proceed with build
ADD . .
RUN go build -o ./bin/flattener ./main.go
RUN chmod +x ./bin/flattener
# use a minimal alpine image
FROM alpine:3.7
# add ca-certificates in case you need them
RUN apk update && apk add ca-certificates && rm -rf /var/cache/apk/*
# set working directory
WORKDIR /root
# copy the binary from builder
COPY --from=builder /go/src/github.com/signoz/signoz/pkg/processors/flattener/bin/flattener .
# run the binary
CMD ["./flattener"]

View File

@ -1,23 +0,0 @@
# Flattener Processor
Flattener Processor is a spream processing application that reads spans from topic `otlp_spans` and writes to topic `flattened_spans`. It is written in **Golang**. Flattener Processor is responsible to convert the incoming spans into a flat model that can be ingested to Apache Druid.
#### Configuration
Flattener Processor needs below `env` variables to run:
```
KAFKA_BROKER: signoz-kafka:9092
KAFKA_INPUT_TOPIC: otlp_spans
KAFKA_OUTPUT_TOPIC: flattened_spans
```
The above values are the default ones used by SigNoz and are kept at `deploy/kubernetes/platform/signoz-charts/flattener-processor/values.yaml`
#### Build and Run locally
```console
cd pkg/processors/flattener
go build -o build/flattener-processor main.go
KAFKA_BROKER=xxxx KAFKA_INPUT_TOPIC=otlp_spans KAFKA_OUTPUT_TOPIC=flattened_spans build/flattener-processor
```
#### Docker Images
The docker images of flattener-processor is available at https://hub.docker.com/r/signoz/flattener-processor

View File

@ -1,10 +0,0 @@
module flattener
go 1.14
require (
gitlab.com/signoz-public/goka v0.0.2
gitlab.com/signoz-public/spanprocessor v0.0.2
go.opentelemetry.io/collector v0.17.0
go.uber.org/zap v1.16.0
)

File diff suppressed because it is too large Load Diff

View File

@ -1,366 +0,0 @@
package main
import (
"context"
"encoding/hex"
"encoding/json"
"fmt"
"os"
"strconv"
"gitlab.com/signoz-public/goka"
sp "gitlab.com/signoz-public/spanprocessor"
"gitlab.com/signoz-public/spanprocessor/consumer/pdata"
"go.opentelemetry.io/collector/translator/conventions"
"go.uber.org/zap"
)
/*
Some error message when processor is kept for running for long duration
1. Restoring from local storage on application restart
2. goka best practices
3. Every persist call writes to kafka topic otel-collector-table with increasing number of spans
4. In Goka a single processor cannot work with 2 stores? What if I need 2 tables?
5. Goka does not have Punctuator analogy
6. The key is used to find the partition. Why do we have just 1 partition?
Notes:
1. goka.Context is changed to have setKey func and correctly read key from []byte using hex.EncodeToString
2. What to do if we receive a span after TIMEOUT_INTERVAL? -> no logic has been implemented
3. go-routines started are never cleared after Done()
4. Delete key from table -> gives error
*/
var (
brokers = []string{os.Getenv("KAFKA_BROKER")}
INPUT_TOPIC goka.Stream = goka.Stream(os.Getenv("KAFKA_INPUT_TOPIC"))
OUTPUT_TOPIC goka.Stream = goka.Stream(os.Getenv("KAFKA_OUTPUT_TOPIC"))
group goka.Group = "flattener"
)
type Span struct {
TraceId string
SpanId string
ParentSpanId string
Name string
DurationNano uint64
StartTimeUnixNano uint64
ServiceName string
Kind int32
References []OtelSpanRef
Tags []string
TagsKeys []string
TagsValues []string
StatusCode int64
ExternalHttpMethod string
ExternalHttpUrl string
Component string
DBSystem string
DBName string
DBOperation string
PeerService string
}
type OtelSpanRef struct {
TraceId string
SpanId string
RefType string
}
var unmarshaller = sp.DefaultUnmarshallers()["otlp_proto"]
var marshaller = sp.DefaultMarshallers()["otlp_proto"]
type OtelCodec struct{}
type OutputCodec struct{}
func (c *OutputCodec) Encode(value interface{}) ([]byte, error) {
// fmt.Println("Encoding to LevelDB ...")
// st := value.(*StructuredTrace)
// for _, span := range st.spans {
// fmt.Println(span.Name)
// }
b, err := json.Marshal(value)
// os.Stderr.Write(b)
return b, err
}
func (c *OutputCodec) Decode(data []byte) (interface{}, error) {
// fmt.Println("Decoding from LevelDB ...")
var ss Span
err := json.Unmarshal(data, &ss)
return &ss, err
}
func (c *OtelCodec) Encode(value interface{}) ([]byte, error) {
// fmt.Println("Encoding Otel Traces ...")
// messages, err = marshaller.Marshal(td)
// return messages, err
return json.Marshal(value)
}
func (c *OtelCodec) Decode(data []byte) (interface{}, error) {
// fmt.Println("Decoding Otel Traces ...")
traces, err := unmarshaller.Unmarshal(data)
// printTraces(&traces)
return &traces, err
}
func makeJaegerProtoReferences(
links pdata.SpanLinkSlice,
parentSpanID pdata.SpanID,
traceID pdata.TraceID,
) ([]OtelSpanRef, error) {
parentSpanIDSet := len(parentSpanID.Bytes()) != 0
if !parentSpanIDSet && links.Len() == 0 {
return nil, nil
}
refsCount := links.Len()
if parentSpanIDSet {
refsCount++
}
refs := make([]OtelSpanRef, 0, refsCount)
// Put parent span ID at the first place because usually backends look for it
// as the first CHILD_OF item in the model.SpanRef slice.
if parentSpanIDSet {
refs = append(refs, OtelSpanRef{
TraceId: traceID.HexString(),
SpanId: parentSpanID.HexString(),
RefType: "CHILD_OF",
})
}
for i := 0; i < links.Len(); i++ {
link := links.At(i)
if link.IsNil() {
continue
}
refs = append(refs, OtelSpanRef{
TraceId: link.TraceID().HexString(),
SpanId: link.SpanID().HexString(),
// Since Jaeger RefType is not captured in internal data,
// use SpanRefType_FOLLOWS_FROM by default.
// SpanRefType_CHILD_OF supposed to be set only from parentSpanID.
RefType: "FOLLOWS_FROM",
})
}
return refs, nil
}
func printTraces(traces_pt *pdata.Traces) {
traces := *traces_pt
rss := traces.ResourceSpans()
for i := 0; i < rss.Len(); i++ {
fmt.Printf("ResourceSpans #%d\n", i)
rs := rss.At(i)
if rs.IsNil() {
fmt.Println("* Nil ResourceSpans")
continue
}
ilss := rs.InstrumentationLibrarySpans()
for j := 0; j < ilss.Len(); j++ {
fmt.Printf("InstrumentationLibrarySpans #%d\n", j)
ils := ilss.At(j)
if ils.IsNil() {
fmt.Printf("* Nil InstrumentationLibrarySpans\n")
continue
}
spans := ils.Spans()
for k := 0; k < spans.Len(); k++ {
span := spans.At(k)
// references := span.Links()
jReferences, _ := makeJaegerProtoReferences(span.Links(), span.ParentSpanID(), span.TraceID())
for _, ref := range jReferences {
fmt.Println(ref.TraceId)
fmt.Println(ref.SpanId)
fmt.Println(ref.RefType)
}
// traceID := hex.EncodeToString(span.TraceID())
traceID_bytes := span.TraceID().Bytes()
traceID := hex.EncodeToString(traceID_bytes[:])
fmt.Println(traceID)
// os.Exit(3)
}
}
}
}
func byteSlice2string(byteSlice []byte) string {
return hex.EncodeToString(byteSlice)
}
func populateOtherDimensions(attributes pdata.AttributeMap, span *Span) {
attributes.ForEach(func(k string, v pdata.AttributeValue) {
if k == "http.status_code" {
span.StatusCode = v.IntVal()
}
if k == "http.url" {
span.ExternalHttpUrl = v.StringVal()
}
if k == "http.method" {
span.ExternalHttpMethod = v.StringVal()
}
if k == "component" {
span.Component = v.StringVal()
}
if k == "db.system" {
span.DBSystem = v.StringVal()
}
if k == "db.name" {
span.DBName = v.StringVal()
}
if k == "db.operation" {
span.DBOperation = v.StringVal()
}
if k == "peer.service" {
span.PeerService = v.StringVal()
}
})
}
func newStructuredSpan(otelSpan pdata.Span, ServiceName string) *Span {
durationNano := uint64(otelSpan.EndTime() - otelSpan.StartTime())
traceID_bytes := otelSpan.TraceID().Bytes()
spanID_bytes := otelSpan.SpanID().Bytes()
parentSpanID_bytes := otelSpan.ParentSpanID().Bytes()
attributes := otelSpan.Attributes()
var tags []string
var tagsKeys []string
var tagsValues []string
var tag string
attributes.ForEach(func(k string, v pdata.AttributeValue) {
if v.Type().String() == "INT" {
tag = fmt.Sprintf("%s:%d", k, v.IntVal())
tagsValues = append(tagsValues, strconv.FormatInt(v.IntVal(), 10))
} else {
tag = fmt.Sprintf("%s:%s", k, v.StringVal())
tagsValues = append(tagsValues, v.StringVal())
}
tags = append(tags, tag)
tagsKeys = append(tagsKeys, k)
})
references, _ := makeJaegerProtoReferences(otelSpan.Links(), otelSpan.ParentSpanID(), otelSpan.TraceID())
var span *Span = &Span{
TraceId: hex.EncodeToString(traceID_bytes[:]),
SpanId: hex.EncodeToString(spanID_bytes[:]),
ParentSpanId: hex.EncodeToString(parentSpanID_bytes[:]),
Name: otelSpan.Name(),
StartTimeUnixNano: uint64(otelSpan.StartTime()),
DurationNano: durationNano,
ServiceName: ServiceName,
Kind: int32(otelSpan.Kind()),
References: references,
Tags: tags,
TagsKeys: tagsKeys,
TagsValues: tagsValues,
}
span.StatusCode = int64(otelSpan.Status().Code())
populateOtherDimensions(attributes, span)
return span
}
// ServiceNameForResource gets the service name for a specified Resource.
// TODO: Find a better package for this function.
func ServiceNameForResource(resource pdata.Resource) string {
// if resource.IsNil() {
// return "<nil-resource>"
// }
service, found := resource.Attributes().Get(conventions.AttributeServiceName)
if !found {
return "<nil-service-name>"
}
return service.StringVal()
}
func process(ctx goka.Context, msg interface{}) {
traces_ptr := msg.(*pdata.Traces)
// printTraces(traces_ptr)
rss := (*traces_ptr).ResourceSpans()
for i := 0; i < rss.Len(); i++ {
// fmt.Printf("ResourceSpans #%d\n", i)
rs := rss.At(i)
if rs.IsNil() {
fmt.Println("* Nil ResourceSpans")
continue
}
serviceName := ServiceNameForResource(rs.Resource())
ilss := rs.InstrumentationLibrarySpans()
for j := 0; j < ilss.Len(); j++ {
// fmt.Printf("InstrumentationLibrarySpans #%d\n", j)
ils := ilss.At(j)
if ils.IsNil() {
fmt.Printf("* Nil InstrumentationLibrarySpans\n")
continue
}
spans := ils.Spans()
for k := 0; k < spans.Len(); k++ {
span := spans.At(k)
// traceID := hex.EncodeToString(span.TraceID())
structuredSpan := newStructuredSpan(span, serviceName)
ctx.Emit(OUTPUT_TOPIC, structuredSpan.TraceId, structuredSpan)
}
}
}
}
func runProcessor() {
g := goka.DefineGroup(group,
goka.Input(INPUT_TOPIC, new(OtelCodec), process),
goka.Output(OUTPUT_TOPIC, new(OutputCodec)),
)
p, err := goka.NewProcessor(brokers, g)
if err != nil {
zap.S().Error(err)
panic(err)
}
zap.S().Info("Running flattener processor ...")
p.Run(context.Background())
}
func main() {
runProcessor()
}

View File

@ -1,4 +1,4 @@
FROM golang:1.14-buster AS builder
FROM golang:1.17-buster AS builder
# LD_FLAGS is passed as argument from Makefile. It will be empty, if no argument passed
ARG LD_FLAGS

View File

@ -1,9 +1,11 @@
package clickhouseReader
import (
"context"
"net/url"
"time"
"github.com/jmoiron/sqlx"
"github.com/ClickHouse/clickhouse-go/v2"
)
type Encoding string
@ -16,13 +18,16 @@ const (
)
const (
defaultDatasource string = "tcp://localhost:9000"
defaultOperationsTable string = "signoz_operations"
defaultIndexTable string = "signoz_index"
defaultErrorTable string = "signoz_error_index"
defaultWriteBatchDelay time.Duration = 5 * time.Second
defaultWriteBatchSize int = 10000
defaultEncoding Encoding = EncodingJSON
defaultDatasource string = "tcp://localhost:9000"
defaultTraceDB string = "signoz_traces"
defaultOperationsTable string = "signoz_operations"
defaultIndexTable string = "signoz_index_v2"
defaultErrorTable string = "signoz_error_index"
defaulDurationTable string = "durationSortMV"
defaultSpansTable string = "signoz_spans"
defaultWriteBatchDelay time.Duration = 5 * time.Second
defaultWriteBatchSize int = 10000
defaultEncoding Encoding = EncodingJSON
)
const (
@ -41,8 +46,10 @@ type namespaceConfig struct {
namespace string
Enabled bool
Datasource string
TraceDB string
OperationsTable string
IndexTable string
DurationTable string
SpansTable string
ErrorTable string
WriteBatchDelay time.Duration
@ -52,15 +59,27 @@ type namespaceConfig struct {
}
// Connecto defines how to connect to the database
type Connector func(cfg *namespaceConfig) (*sqlx.DB, error)
type Connector func(cfg *namespaceConfig) (clickhouse.Conn, error)
func defaultConnector(cfg *namespaceConfig) (*sqlx.DB, error) {
db, err := sqlx.Open("clickhouse", cfg.Datasource)
func defaultConnector(cfg *namespaceConfig) (clickhouse.Conn, error) {
ctx := context.Background()
dsnURL, err := url.Parse(cfg.Datasource)
options := &clickhouse.Options{
Addr: []string{dsnURL.Host},
}
if dsnURL.Query().Get("username") != "" {
auth := clickhouse.Auth{
Username: dsnURL.Query().Get("username"),
Password: dsnURL.Query().Get("password"),
}
options.Auth = auth
}
db, err := clickhouse.Open(options)
if err != nil {
return nil, err
}
if err := db.Ping(); err != nil {
if err := db.Ping(ctx); err != nil {
return nil, err
}
@ -86,9 +105,12 @@ func NewOptions(datasource string, primaryNamespace string, otherNamespaces ...s
namespace: primaryNamespace,
Enabled: true,
Datasource: datasource,
TraceDB: defaultTraceDB,
OperationsTable: defaultOperationsTable,
IndexTable: defaultIndexTable,
ErrorTable: defaultErrorTable,
DurationTable: defaulDurationTable,
SpansTable: defaultSpansTable,
WriteBatchDelay: defaultWriteBatchDelay,
WriteBatchSize: defaultWriteBatchSize,
Encoding: defaultEncoding,
@ -102,6 +124,7 @@ func NewOptions(datasource string, primaryNamespace string, otherNamespaces ...s
options.others[namespace] = &namespaceConfig{
namespace: namespace,
Datasource: datasource,
TraceDB: "",
OperationsTable: "",
IndexTable: "",
ErrorTable: "",

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,29 @@
package clickhouseReader
import (
"testing"
"github.com/stretchr/testify/assert"
)
type GetStatusFiltersTest struct {
query string
statusParams []string
excludeMap map[string]struct{}
expected string
}
func TestGetStatusFilters(t *testing.T) {
assert := assert.New(t)
var tests = []GetStatusFiltersTest{
{"", make([]string, 0), map[string]struct{}{}, ""},
{"test", []string{"error"}, map[string]struct{}{}, "test AND hasError = true"},
{"test", []string{"ok"}, map[string]struct{}{}, "test AND hasError = false"},
{"test", []string{"error"}, map[string]struct{}{"status": {}}, "test AND hasError = false"},
{"test", []string{"ok"}, map[string]struct{}{"status": {}}, "test AND hasError = true"},
{"test", []string{"error", "ok"}, map[string]struct{}{}, "test"},
}
for _, test := range tests {
assert.Equal(getStatusFilters(test.query, test.statusParams, test.excludeMap), test.expected)
}
}

View File

@ -36,7 +36,7 @@ func InitDB(dataSourceName string) (*sqlx.DB, error) {
_, err = db.Exec(table_schema)
if err != nil {
return nil, fmt.Errorf("Error in creating dashboard table: %v", err)
return nil, fmt.Errorf("Error in creating dashboard table: %s", err.Error())
}
table_schema = `CREATE TABLE IF NOT EXISTS rules (
@ -48,7 +48,7 @@ func InitDB(dataSourceName string) (*sqlx.DB, error) {
_, err = db.Exec(table_schema)
if err != nil {
return nil, fmt.Errorf("Error in creating rules table: %v", err)
return nil, fmt.Errorf("Error in creating rules table: %s", err.Error())
}
table_schema = `CREATE TABLE IF NOT EXISTS notification_channels (
@ -63,7 +63,7 @@ func InitDB(dataSourceName string) (*sqlx.DB, error) {
_, err = db.Exec(table_schema)
if err != nil {
return nil, fmt.Errorf("Error in creating notification_channles table: %v", err)
return nil, fmt.Errorf("Error in creating notification_channles table: %s", err.Error())
}
return db, nil

View File

@ -18,7 +18,6 @@ func readCurrentDir(dir string) error {
list, _ := file.Readdirnames(0) // 0 to read all files and folders
for _, filename := range list {
// fmt.Println(filename)
zap.S().Info("Provisioning dashboard: ", filename)
plan, err := ioutil.ReadFile(dir + "/" + filename)
if err != nil {

View File

@ -1,203 +0,0 @@
package druidReader
import (
"context"
"fmt"
"os"
"github.com/jmoiron/sqlx"
"github.com/prometheus/prometheus/promql"
"github.com/prometheus/prometheus/util/stats"
"go.signoz.io/query-service/druidQuery"
"go.signoz.io/query-service/godruid"
"go.signoz.io/query-service/model"
am "go.signoz.io/query-service/integrations/alertManager"
)
type DruidReader struct {
Client *godruid.Client
SqlClient *druidQuery.SqlClient
LocalDB *sqlx.DB
}
func NewReader(localDB *sqlx.DB) *DruidReader {
initialize()
druidClientUrl := os.Getenv("DruidClientUrl")
client := godruid.Client{
Url: druidClientUrl,
Debug: true,
}
sqlClient := druidQuery.SqlClient{
Url: druidClientUrl,
Debug: true,
}
return &DruidReader{
Client: &client,
SqlClient: &sqlClient,
LocalDB: localDB,
}
}
func initialize() {
}
func (druid *DruidReader) GetQueryRangeResult(ctx context.Context, query *model.QueryRangeParams) (*promql.Result, *stats.QueryStats, *model.ApiError) {
return nil, nil, &model.ApiError{model.ErrorNotImplemented, fmt.Errorf("Druid does not support metrics")}
}
func (druid *DruidReader) GetInstantQueryMetricsResult(ctx context.Context, query *model.InstantQueryMetricsParams) (*promql.Result, *stats.QueryStats, *model.ApiError) {
return nil, nil, &model.ApiError{model.ErrorNotImplemented, fmt.Errorf("Druid does not support metrics")}
}
func (druid *DruidReader) DeleteChannel(id string) *model.ApiError {
return &model.ApiError{model.ErrorNotImplemented, fmt.Errorf("Druid does not support notification channel for alerts")}
}
func (druid *DruidReader) GetChannel(id string) (*model.ChannelItem, *model.ApiError) {
return nil, &model.ApiError{model.ErrorNotImplemented, fmt.Errorf("Druid does not support notification channel for alerts")}
}
func (druid *DruidReader) GetChannels() (*[]model.ChannelItem, *model.ApiError) {
return nil, &model.ApiError{model.ErrorNotImplemented, fmt.Errorf("Druid does not support notification channel for alerts")}
}
func (druid *DruidReader) CreateChannel(receiver *am.Receiver) (*am.Receiver, *model.ApiError) {
return nil, &model.ApiError{model.ErrorNotImplemented, fmt.Errorf("Druid does not support notification channel for alerts")}
}
func (druid *DruidReader) EditChannel(receiver *am.Receiver, id string) (*am.Receiver, *model.ApiError) {
return nil, &model.ApiError{model.ErrorNotImplemented, fmt.Errorf("Druid does not support notification channel for alerts")}
}
func (druid *DruidReader) ListRulesFromProm() (*model.AlertDiscovery, *model.ApiError) {
res := model.AlertDiscovery{}
return &res, &model.ApiError{model.ErrorNotImplemented, fmt.Errorf("Druid does not support getting rules for alerting")}
}
func (druid *DruidReader) GetRule(id string) (*model.RuleResponseItem, *model.ApiError) {
return nil, &model.ApiError{model.ErrorNotImplemented, fmt.Errorf("Druid does not support getting rules for alerting")}
}
func (druid *DruidReader) CreateRule(alert string) *model.ApiError {
return &model.ApiError{model.ErrorNotImplemented, fmt.Errorf("Druid does not support setting rules for alerting")}
}
func (druid *DruidReader) EditRule(alert string, id string) *model.ApiError {
return &model.ApiError{model.ErrorNotImplemented, fmt.Errorf("Druid does not support editing rules for alerting")}
}
func (druid *DruidReader) DeleteRule(id string) *model.ApiError {
return &model.ApiError{model.ErrorNotImplemented, fmt.Errorf("Druid does not support deleting rules for alerting")}
}
func (druid *DruidReader) GetServiceOverview(ctx context.Context, query *model.GetServiceOverviewParams) (*[]model.ServiceOverviewItem, error) {
return druidQuery.GetServiceOverview(druid.SqlClient, query)
}
func (druid *DruidReader) GetServices(ctx context.Context, query *model.GetServicesParams) (*[]model.ServiceItem, error) {
return druidQuery.GetServices(druid.SqlClient, query)
}
func (druid *DruidReader) SearchSpans(ctx context.Context, query *model.SpanSearchParams) (*[]model.SearchSpansResult, error) {
return druidQuery.SearchSpans(druid.Client, query)
}
func (druid *DruidReader) GetServiceDBOverview(ctx context.Context, query *model.GetServiceOverviewParams) (*[]model.ServiceDBOverviewItem, error) {
return druidQuery.GetServiceDBOverview(druid.SqlClient, query)
}
func (druid *DruidReader) GetServiceExternalAvgDuration(ctx context.Context, query *model.GetServiceOverviewParams) (*[]model.ServiceExternalItem, error) {
return druidQuery.GetServiceExternalAvgDuration(druid.SqlClient, query)
}
func (druid *DruidReader) GetServiceExternalErrors(ctx context.Context, query *model.GetServiceOverviewParams) (*[]model.ServiceExternalItem, error) {
return druidQuery.GetServiceExternalErrors(druid.SqlClient, query)
}
func (druid *DruidReader) GetServiceExternal(ctx context.Context, query *model.GetServiceOverviewParams) (*[]model.ServiceExternalItem, error) {
return druidQuery.GetServiceExternal(druid.SqlClient, query)
}
func (druid *DruidReader) GetTopEndpoints(ctx context.Context, query *model.GetTopEndpointsParams) (*[]model.TopEndpointsItem, error) {
return druidQuery.GetTopEndpoints(druid.SqlClient, query)
}
func (druid *DruidReader) GetUsage(ctx context.Context, query *model.GetUsageParams) (*[]model.UsageItem, error) {
return druidQuery.GetUsage(druid.SqlClient, query)
}
func (druid *DruidReader) GetOperations(ctx context.Context, serviceName string) (*[]string, error) {
return druidQuery.GetOperations(druid.SqlClient, serviceName)
}
func (druid *DruidReader) GetTags(ctx context.Context, serviceName string) (*[]model.TagItem, error) {
return druidQuery.GetTags(druid.SqlClient, serviceName)
}
func (druid *DruidReader) GetServicesList(ctx context.Context) (*[]string, error) {
return druidQuery.GetServicesList(druid.SqlClient)
}
func (druid *DruidReader) SearchTraces(ctx context.Context, traceId string) (*[]model.SearchSpansResult, error) {
return druidQuery.SearchTraces(druid.Client, traceId)
}
func (druid *DruidReader) GetServiceMapDependencies(ctx context.Context, query *model.GetServicesParams) (*[]model.ServiceMapDependencyResponseItem, error) {
return druidQuery.GetServiceMapDependencies(druid.SqlClient, query)
}
func (druid *DruidReader) SearchSpansAggregate(ctx context.Context, queryParams *model.SpanSearchAggregatesParams) ([]model.SpanSearchAggregatesResponseItem, error) {
return druidQuery.SearchSpansAggregate(druid.Client, queryParams)
}
func (druid *DruidReader) SetTTL(_ context.Context, _ *model.TTLParams) (*model.SetTTLResponseItem, *model.ApiError) {
return nil, &model.ApiError{model.ErrorNotImplemented, fmt.Errorf("druid does not support setting ttl configuration")}
}
func (druid *DruidReader) GetDisks(ctx context.Context) (*[]model.DiskItem, *model.ApiError) {
return nil, &model.ApiError{model.ErrorNotImplemented, fmt.Errorf("druid does not support getting disk list")}
}
func (druid *DruidReader) GetTTL(_ context.Context, _ *model.GetTTLParams) (*model.GetTTLResponseItem, *model.ApiError) {
return nil, &model.ApiError{model.ErrorNotImplemented, fmt.Errorf("druid does not support setting ttl configuration")}
}
func (druid *DruidReader) GetSpanFilters(_ context.Context, _ *model.SpanFilterParams) (*model.SpanFiltersResponse, *model.ApiError) {
return nil, &model.ApiError{model.ErrorNotImplemented, fmt.Errorf("druid does not support getting spanfilters")}
}
func (druid *DruidReader) GetTagFilters(_ context.Context, _ *model.TagFilterParams) (*[]model.TagFilters, *model.ApiError) {
return nil, &model.ApiError{model.ErrorNotImplemented, fmt.Errorf("druid does not support getting tagFilters")}
}
func (druid *DruidReader) GetTagValues(_ context.Context, _ *model.TagFilterParams) (*[]model.TagValues, *model.ApiError) {
return nil, &model.ApiError{model.ErrorNotImplemented, fmt.Errorf("druid does not support getting tagValues")}
}
func (druid *DruidReader) GetFilteredSpans(_ context.Context, _ *model.GetFilteredSpansParams) (*model.GetFilterSpansResponse, *model.ApiError) {
return nil, &model.ApiError{model.ErrorNotImplemented, fmt.Errorf("druid does not support getting FilteredSpans")}
}
func (druid *DruidReader) GetFilteredSpansAggregates(_ context.Context, _ *model.GetFilteredSpanAggregatesParams) (*model.GetFilteredSpansAggregatesResponse, *model.ApiError) {
return nil, &model.ApiError{model.ErrorNotImplemented, fmt.Errorf("druid does not support getting FilteredSpans")}
}
func (druid *DruidReader) GetErrors(_ context.Context, _ *model.GetErrorsParams) (*[]model.Error, *model.ApiError) {
return nil, &model.ApiError{model.ErrorNotImplemented, fmt.Errorf("druid does not support get error API")}
}
func (druid *DruidReader) GetErrorForId(_ context.Context, _ *model.GetErrorParams) (*model.ErrorWithSpan, *model.ApiError) {
return nil, &model.ApiError{model.ErrorNotImplemented, fmt.Errorf("druid does not support get error API")}
}
func (druid *DruidReader) GetErrorForType(_ context.Context, _ *model.GetErrorParams) (*model.ErrorWithSpan, *model.ApiError) {
return nil, &model.ApiError{model.ErrorNotImplemented, fmt.Errorf("druid does not support get error API")}
}

View File

@ -12,6 +12,7 @@ import (
_ "github.com/mattn/go-sqlite3"
"github.com/prometheus/prometheus/promql"
"go.signoz.io/query-service/app/dashboards"
"go.signoz.io/query-service/app/parser"
"go.signoz.io/query-service/dao/interfaces"
am "go.signoz.io/query-service/integrations/alertManager"
"go.signoz.io/query-service/model"
@ -165,6 +166,13 @@ func (aH *APIHandler) respond(w http.ResponseWriter, data interface{}) {
zap.S().Error("msg", "error writing response", "bytesWritten", n, "err", err)
}
}
func (aH *APIHandler) RegisterMetricsRoutes(router *mux.Router) {
subRouter := router.PathPrefix("/api/v2/metrics").Subrouter()
subRouter.HandleFunc("/query_range", aH.queryRangeMetricsV2).Methods(http.MethodPost)
subRouter.HandleFunc("/autocomplete/list", aH.metricAutocompleteMetricName).Methods(http.MethodGet)
subRouter.HandleFunc("/autocomplete/tagKey", aH.metricAutocompleteTagKey).Methods(http.MethodGet)
subRouter.HandleFunc("/autocomplete/tagValue", aH.metricAutocompleteTagValue).Methods(http.MethodGet)
}
// RegisterRoutes registers routes for this handler on the given router
func (aH *APIHandler) RegisterRoutes(router *mux.Router) {
@ -192,18 +200,10 @@ func (aH *APIHandler) RegisterRoutes(router *mux.Router) {
router.HandleFunc("/api/v1/feedback", aH.submitFeedback).Methods(http.MethodPost)
// router.HandleFunc("/api/v1/get_percentiles", aH.getApplicationPercentiles).Methods(http.MethodGet)
router.HandleFunc("/api/v1/services", aH.getServices).Methods(http.MethodGet)
router.HandleFunc("/api/v1/services", aH.getServices).Methods(http.MethodPost)
router.HandleFunc("/api/v1/services/list", aH.getServicesList).Methods(http.MethodGet)
router.HandleFunc("/api/v1/service/overview", aH.getServiceOverview).Methods(http.MethodGet)
router.HandleFunc("/api/v1/service/dbOverview", aH.getServiceDBOverview).Methods(http.MethodGet)
router.HandleFunc("/api/v1/service/externalAvgDuration", aH.GetServiceExternalAvgDuration).Methods(http.MethodGet)
router.HandleFunc("/api/v1/service/externalErrors", aH.getServiceExternalErrors).Methods(http.MethodGet)
router.HandleFunc("/api/v1/service/external", aH.getServiceExternal).Methods(http.MethodGet)
router.HandleFunc("/api/v1/service/{service}/operations", aH.getOperations).Methods(http.MethodGet)
router.HandleFunc("/api/v1/service/top_endpoints", aH.getTopEndpoints).Methods(http.MethodGet)
router.HandleFunc("/api/v1/spans", aH.searchSpans).Methods(http.MethodGet)
router.HandleFunc("/api/v1/spans/aggregates", aH.searchSpansAggregates).Methods(http.MethodGet)
router.HandleFunc("/api/v1/tags", aH.searchTags).Methods(http.MethodGet)
router.HandleFunc("/api/v1/service/overview", aH.getServiceOverview).Methods(http.MethodPost)
router.HandleFunc("/api/v1/service/top_endpoints", aH.getTopEndpoints).Methods(http.MethodPost)
router.HandleFunc("/api/v1/traces/{traceId}", aH.searchTraces).Methods(http.MethodGet)
router.HandleFunc("/api/v1/usage", aH.getUsage).Methods(http.MethodGet)
router.HandleFunc("/api/v1/serviceMapDependencies", aH.serviceMapDependencies).Methods(http.MethodGet)
@ -252,6 +252,74 @@ func (aH *APIHandler) getRule(w http.ResponseWriter, r *http.Request) {
aH.respond(w, alertList)
}
func (aH *APIHandler) metricAutocompleteMetricName(w http.ResponseWriter, r *http.Request) {
matchText := r.URL.Query().Get("match")
metricNameList, apiErrObj := (*aH.reader).GetMetricAutocompleteMetricNames(r.Context(), matchText)
if apiErrObj != nil {
aH.respondError(w, apiErrObj, nil)
return
}
aH.respond(w, metricNameList)
}
func (aH *APIHandler) metricAutocompleteTagKey(w http.ResponseWriter, r *http.Request) {
metricsAutocompleteTagKeyParams, apiErrorObj := parser.ParseMetricAutocompleteTagParams(r)
if apiErrorObj != nil {
aH.respondError(w, apiErrorObj, nil)
return
}
tagKeyList, apiErrObj := (*aH.reader).GetMetricAutocompleteTagKey(r.Context(), metricsAutocompleteTagKeyParams)
if apiErrObj != nil {
aH.respondError(w, apiErrObj, nil)
return
}
aH.respond(w, tagKeyList)
}
func (aH *APIHandler) metricAutocompleteTagValue(w http.ResponseWriter, r *http.Request) {
metricsAutocompleteTagValueParams, apiErrorObj := parser.ParseMetricAutocompleteTagParams(r)
if len(metricsAutocompleteTagValueParams.TagKey) == 0 {
apiErrObj := &model.ApiError{Typ: model.ErrorBadData, Err: fmt.Errorf("tagKey not present in params")}
aH.respondError(w, apiErrObj, nil)
return
}
if apiErrorObj != nil {
aH.respondError(w, apiErrorObj, nil)
return
}
tagValueList, apiErrObj := (*aH.reader).GetMetricAutocompleteTagValue(r.Context(), metricsAutocompleteTagValueParams)
if apiErrObj != nil {
aH.respondError(w, apiErrObj, nil)
return
}
aH.respond(w, tagValueList)
}
func (aH *APIHandler) queryRangeMetricsV2(w http.ResponseWriter, r *http.Request) {
metricsQueryRangeParams, apiErrorObj := parser.ParseMetricQueryRangeParams(r)
fmt.Println(metricsQueryRangeParams)
if apiErrorObj != nil {
zap.S().Errorf(apiErrorObj.Err.Error())
aH.respondError(w, apiErrorObj, nil)
return
}
response_data := &model.QueryDataV2{
ResultType: "matrix",
Result: nil,
}
aH.respond(w, response_data)
}
func (aH *APIHandler) listRulesFromProm(w http.ResponseWriter, r *http.Request) {
alertList, apiErrorObj := (*aH.reader).ListRulesFromProm()
if apiErrorObj != nil {
@ -562,7 +630,9 @@ func (aH *APIHandler) createRule(w http.ResponseWriter, r *http.Request) {
aH.respond(w, "rule successfully added")
}
func (aH *APIHandler) queryRangeMetricsFromClickhouse(w http.ResponseWriter, r *http.Request) {
}
func (aH *APIHandler) queryRangeMetrics(w http.ResponseWriter, r *http.Request) {
query, apiErrorObj := parseQueryRangeRequest(r)
@ -600,11 +670,11 @@ func (aH *APIHandler) queryRangeMetrics(w http.ResponseWriter, r *http.Request)
if res.Err != nil {
switch res.Err.(type) {
case promql.ErrQueryCanceled:
aH.respondError(w, &model.ApiError{model.ErrorCanceled, res.Err}, nil)
aH.respondError(w, &model.ApiError{Typ: model.ErrorCanceled, Err: res.Err}, nil)
case promql.ErrQueryTimeout:
aH.respondError(w, &model.ApiError{model.ErrorTimeout, res.Err}, nil)
aH.respondError(w, &model.ApiError{Typ: model.ErrorTimeout, Err: res.Err}, nil)
}
aH.respondError(w, &model.ApiError{model.ErrorExec, res.Err}, nil)
aH.respondError(w, &model.ApiError{Typ: model.ErrorExec, Err: res.Err}, nil)
}
response_data := &model.QueryData{
@ -654,11 +724,11 @@ func (aH *APIHandler) queryMetrics(w http.ResponseWriter, r *http.Request) {
if res.Err != nil {
switch res.Err.(type) {
case promql.ErrQueryCanceled:
aH.respondError(w, &model.ApiError{model.ErrorCanceled, res.Err}, nil)
aH.respondError(w, &model.ApiError{Typ: model.ErrorCanceled, Err: res.Err}, nil)
case promql.ErrQueryTimeout:
aH.respondError(w, &model.ApiError{model.ErrorTimeout, res.Err}, nil)
aH.respondError(w, &model.ApiError{Typ: model.ErrorTimeout, Err: res.Err}, nil)
}
aH.respondError(w, &model.ApiError{model.ErrorExec, res.Err}, nil)
aH.respondError(w, &model.ApiError{Typ: model.ErrorExec, Err: res.Err}, nil)
}
response_data := &model.QueryData{
@ -720,52 +790,6 @@ func (aH *APIHandler) user(w http.ResponseWriter, r *http.Request) {
}
func (aH *APIHandler) getOperations(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
serviceName := vars["service"]
var err error
if len(serviceName) == 0 {
err = fmt.Errorf("service param not found")
}
if aH.handleError(w, err, http.StatusBadRequest) {
return
}
result, err := (*aH.reader).GetOperations(context.Background(), serviceName)
if aH.handleError(w, err, http.StatusBadRequest) {
return
}
aH.writeJSON(w, r, result)
}
func (aH *APIHandler) getServicesList(w http.ResponseWriter, r *http.Request) {
result, err := (*aH.reader).GetServicesList(context.Background())
if aH.handleError(w, err, http.StatusBadRequest) {
return
}
aH.writeJSON(w, r, result)
}
func (aH *APIHandler) searchTags(w http.ResponseWriter, r *http.Request) {
serviceName := r.URL.Query().Get("service")
result, err := (*aH.reader).GetTags(context.Background(), serviceName)
if aH.handleError(w, err, http.StatusBadRequest) {
return
}
aH.writeJSON(w, r, result)
}
func (aH *APIHandler) getTopEndpoints(w http.ResponseWriter, r *http.Request) {
query, err := parseGetTopEndpointsRequest(r)
@ -773,9 +797,9 @@ func (aH *APIHandler) getTopEndpoints(w http.ResponseWriter, r *http.Request) {
return
}
result, err := (*aH.reader).GetTopEndpoints(context.Background(), query)
result, apiErr := (*aH.reader).GetTopEndpoints(r.Context(), query)
if aH.handleError(w, err, http.StatusBadRequest) {
if apiErr != nil && aH.handleError(w, apiErr.Err, http.StatusInternalServerError) {
return
}
@ -790,72 +814,7 @@ func (aH *APIHandler) getUsage(w http.ResponseWriter, r *http.Request) {
return
}
result, err := (*aH.reader).GetUsage(context.Background(), query)
if aH.handleError(w, err, http.StatusBadRequest) {
return
}
aH.writeJSON(w, r, result)
}
func (aH *APIHandler) getServiceDBOverview(w http.ResponseWriter, r *http.Request) {
query, err := parseGetServiceExternalRequest(r)
if aH.handleError(w, err, http.StatusBadRequest) {
return
}
result, err := (*aH.reader).GetServiceDBOverview(context.Background(), query)
if aH.handleError(w, err, http.StatusBadRequest) {
return
}
aH.writeJSON(w, r, result)
}
func (aH *APIHandler) getServiceExternal(w http.ResponseWriter, r *http.Request) {
query, err := parseGetServiceExternalRequest(r)
if aH.handleError(w, err, http.StatusBadRequest) {
return
}
result, err := (*aH.reader).GetServiceExternal(context.Background(), query)
if aH.handleError(w, err, http.StatusBadRequest) {
return
}
aH.writeJSON(w, r, result)
}
func (aH *APIHandler) GetServiceExternalAvgDuration(w http.ResponseWriter, r *http.Request) {
query, err := parseGetServiceExternalRequest(r)
if aH.handleError(w, err, http.StatusBadRequest) {
return
}
result, err := (*aH.reader).GetServiceExternalAvgDuration(context.Background(), query)
if aH.handleError(w, err, http.StatusBadRequest) {
return
}
aH.writeJSON(w, r, result)
}
func (aH *APIHandler) getServiceExternalErrors(w http.ResponseWriter, r *http.Request) {
query, err := parseGetServiceExternalRequest(r)
if aH.handleError(w, err, http.StatusBadRequest) {
return
}
result, err := (*aH.reader).GetServiceExternalErrors(context.Background(), query)
result, err := (*aH.reader).GetUsage(r.Context(), query)
if aH.handleError(w, err, http.StatusBadRequest) {
return
}
@ -871,8 +830,8 @@ func (aH *APIHandler) getServiceOverview(w http.ResponseWriter, r *http.Request)
return
}
result, err := (*aH.reader).GetServiceOverview(context.Background(), query)
if aH.handleError(w, err, http.StatusBadRequest) {
result, apiErr := (*aH.reader).GetServiceOverview(r.Context(), query)
if apiErr != nil && aH.handleError(w, apiErr.Err, http.StatusInternalServerError) {
return
}
@ -887,8 +846,8 @@ func (aH *APIHandler) getServices(w http.ResponseWriter, r *http.Request) {
return
}
result, err := (*aH.reader).GetServices(context.Background(), query)
if aH.handleError(w, err, http.StatusBadRequest) {
result, apiErr := (*aH.reader).GetServices(r.Context(), query)
if apiErr != nil && aH.handleError(w, apiErr.Err, http.StatusInternalServerError) {
return
}
@ -908,7 +867,7 @@ func (aH *APIHandler) serviceMapDependencies(w http.ResponseWriter, r *http.Requ
return
}
result, err := (*aH.reader).GetServiceMapDependencies(context.Background(), query)
result, err := (*aH.reader).GetServiceMapDependencies(r.Context(), query)
if aH.handleError(w, err, http.StatusBadRequest) {
return
}
@ -916,12 +875,23 @@ func (aH *APIHandler) serviceMapDependencies(w http.ResponseWriter, r *http.Requ
aH.writeJSON(w, r, result)
}
func (aH *APIHandler) getServicesList(w http.ResponseWriter, r *http.Request) {
result, err := (*aH.reader).GetServicesList(r.Context())
if aH.handleError(w, err, http.StatusBadRequest) {
return
}
aH.writeJSON(w, r, result)
}
func (aH *APIHandler) searchTraces(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
traceId := vars["traceId"]
result, err := (*aH.reader).SearchTraces(context.Background(), traceId)
result, err := (*aH.reader).SearchTraces(r.Context(), traceId)
if aH.handleError(w, err, http.StatusBadRequest) {
return
}
@ -936,7 +906,7 @@ func (aH *APIHandler) getErrors(w http.ResponseWriter, r *http.Request) {
if aH.handleError(w, err, http.StatusBadRequest) {
return
}
result, apiErr := (*aH.reader).GetErrors(context.Background(), query)
result, apiErr := (*aH.reader).GetErrors(r.Context(), query)
if apiErr != nil && aH.handleError(w, apiErr.Err, http.StatusInternalServerError) {
return
}
@ -951,7 +921,7 @@ func (aH *APIHandler) getErrorForId(w http.ResponseWriter, r *http.Request) {
if aH.handleError(w, err, http.StatusBadRequest) {
return
}
result, apiErr := (*aH.reader).GetErrorForId(context.Background(), query)
result, apiErr := (*aH.reader).GetErrorForId(r.Context(), query)
if apiErr != nil && aH.handleError(w, apiErr.Err, http.StatusInternalServerError) {
return
}
@ -966,7 +936,7 @@ func (aH *APIHandler) getErrorForType(w http.ResponseWriter, r *http.Request) {
if aH.handleError(w, err, http.StatusBadRequest) {
return
}
result, apiErr := (*aH.reader).GetErrorForType(context.Background(), query)
result, apiErr := (*aH.reader).GetErrorForType(r.Context(), query)
if apiErr != nil && aH.handleError(w, apiErr.Err, http.StatusInternalServerError) {
return
}
@ -975,38 +945,6 @@ func (aH *APIHandler) getErrorForType(w http.ResponseWriter, r *http.Request) {
}
func (aH *APIHandler) searchSpansAggregates(w http.ResponseWriter, r *http.Request) {
query, err := parseSearchSpanAggregatesRequest(r)
if aH.handleError(w, err, http.StatusBadRequest) {
return
}
result, err := (*aH.reader).SearchSpansAggregate(context.Background(), query)
if aH.handleError(w, err, http.StatusBadRequest) {
return
}
aH.writeJSON(w, r, result)
}
func (aH *APIHandler) searchSpans(w http.ResponseWriter, r *http.Request) {
query, err := parseSpanSearchRequest(r)
if aH.handleError(w, err, http.StatusBadRequest) {
return
}
// result, err := druidQuery.SearchSpans(aH.client, query)
result, err := (*aH.reader).SearchSpans(context.Background(), query)
if aH.handleError(w, err, http.StatusBadRequest) {
return
}
aH.writeJSON(w, r, result)
}
func (aH *APIHandler) getSpanFilters(w http.ResponseWriter, r *http.Request) {
query, err := parseSpanFilterRequestBody(r)
@ -1014,7 +952,7 @@ func (aH *APIHandler) getSpanFilters(w http.ResponseWriter, r *http.Request) {
return
}
result, apiErr := (*aH.reader).GetSpanFilters(context.Background(), query)
result, apiErr := (*aH.reader).GetSpanFilters(r.Context(), query)
if apiErr != nil && aH.handleError(w, apiErr.Err, http.StatusInternalServerError) {
return
@ -1030,7 +968,7 @@ func (aH *APIHandler) getFilteredSpans(w http.ResponseWriter, r *http.Request) {
return
}
result, apiErr := (*aH.reader).GetFilteredSpans(context.Background(), query)
result, apiErr := (*aH.reader).GetFilteredSpans(r.Context(), query)
if apiErr != nil && aH.handleError(w, apiErr.Err, http.StatusInternalServerError) {
return
@ -1046,7 +984,7 @@ func (aH *APIHandler) getFilteredSpanAggregates(w http.ResponseWriter, r *http.R
return
}
result, apiErr := (*aH.reader).GetFilteredSpansAggregates(context.Background(), query)
result, apiErr := (*aH.reader).GetFilteredSpansAggregates(r.Context(), query)
if apiErr != nil && aH.handleError(w, apiErr.Err, http.StatusInternalServerError) {
return
@ -1062,7 +1000,7 @@ func (aH *APIHandler) getTagFilters(w http.ResponseWriter, r *http.Request) {
return
}
result, apiErr := (*aH.reader).GetTagFilters(context.Background(), query)
result, apiErr := (*aH.reader).GetTagFilters(r.Context(), query)
if apiErr != nil && aH.handleError(w, apiErr.Err, http.StatusInternalServerError) {
return
@ -1078,7 +1016,7 @@ func (aH *APIHandler) getTagValues(w http.ResponseWriter, r *http.Request) {
return
}
result, apiErr := (*aH.reader).GetTagValues(context.Background(), query)
result, apiErr := (*aH.reader).GetTagValues(r.Context(), query)
if apiErr != nil && aH.handleError(w, apiErr.Err, http.StatusInternalServerError) {
return
@ -1093,6 +1031,7 @@ func (aH *APIHandler) setTTL(w http.ResponseWriter, r *http.Request) {
return
}
// Context is not used here as TTL is long duration operation which needs to converted to async
result, apiErr := (*aH.reader).SetTTL(context.Background(), ttlParams)
if apiErr != nil && aH.handleError(w, apiErr.Err, http.StatusInternalServerError) {
return
@ -1108,7 +1047,7 @@ func (aH *APIHandler) getTTL(w http.ResponseWriter, r *http.Request) {
return
}
result, apiErr := (*aH.reader).GetTTL(context.Background(), ttlParams)
result, apiErr := (*aH.reader).GetTTL(r.Context(), ttlParams)
if apiErr != nil && aH.handleError(w, apiErr.Err, http.StatusInternalServerError) {
return
}
@ -1127,7 +1066,7 @@ func (aH *APIHandler) getDisks(w http.ResponseWriter, r *http.Request) {
func (aH *APIHandler) getUserPreferences(w http.ResponseWriter, r *http.Request) {
result, apiError := (*aH.relationalDB).FetchUserPreference(context.Background())
result, apiError := (*aH.relationalDB).FetchUserPreference(r.Context())
if apiError != nil {
aH.respondError(w, apiError, "Error from Fetch Dao")
return
@ -1142,7 +1081,7 @@ func (aH *APIHandler) setUserPreferences(w http.ResponseWriter, r *http.Request)
return
}
apiErr := (*aH.relationalDB).UpdateUserPreferece(context.Background(), userParams)
apiErr := (*aH.relationalDB).UpdateUserPreferece(r.Context(), userParams)
if apiErr != nil && aH.handleError(w, apiErr.Err, http.StatusInternalServerError) {
return
}

View File

@ -5,8 +5,8 @@ import (
"github.com/prometheus/prometheus/promql"
"github.com/prometheus/prometheus/util/stats"
"go.signoz.io/query-service/model"
am "go.signoz.io/query-service/integrations/alertManager"
"go.signoz.io/query-service/model"
)
type Reader interface {
@ -24,17 +24,11 @@ type Reader interface {
GetInstantQueryMetricsResult(ctx context.Context, query *model.InstantQueryMetricsParams) (*promql.Result, *stats.QueryStats, *model.ApiError)
GetQueryRangeResult(ctx context.Context, query *model.QueryRangeParams) (*promql.Result, *stats.QueryStats, *model.ApiError)
GetServiceOverview(ctx context.Context, query *model.GetServiceOverviewParams) (*[]model.ServiceOverviewItem, error)
GetServices(ctx context.Context, query *model.GetServicesParams) (*[]model.ServiceItem, error)
GetServiceOverview(ctx context.Context, query *model.GetServiceOverviewParams) (*[]model.ServiceOverviewItem, *model.ApiError)
GetServices(ctx context.Context, query *model.GetServicesParams) (*[]model.ServiceItem, *model.ApiError)
// GetApplicationPercentiles(ctx context.Context, query *model.ApplicationPercentileParams) ([]godruid.Timeseries, error)
GetServiceDBOverview(ctx context.Context, query *model.GetServiceOverviewParams) (*[]model.ServiceDBOverviewItem, error)
GetServiceExternalAvgDuration(ctx context.Context, query *model.GetServiceOverviewParams) (*[]model.ServiceExternalItem, error)
GetServiceExternalErrors(ctx context.Context, query *model.GetServiceOverviewParams) (*[]model.ServiceExternalItem, error)
GetServiceExternal(ctx context.Context, query *model.GetServiceOverviewParams) (*[]model.ServiceExternalItem, error)
GetTopEndpoints(ctx context.Context, query *model.GetTopEndpointsParams) (*[]model.TopEndpointsItem, error)
GetTopEndpoints(ctx context.Context, query *model.GetTopEndpointsParams) (*[]model.TopEndpointsItem, *model.ApiError)
GetUsage(ctx context.Context, query *model.GetUsageParams) (*[]model.UsageItem, error)
GetOperations(ctx context.Context, serviceName string) (*[]string, error)
GetTags(ctx context.Context, serviceName string) (*[]model.TagItem, error)
GetServicesList(ctx context.Context) (*[]string, error)
GetServiceMapDependencies(ctx context.Context, query *model.GetServicesParams) (*[]model.ServiceMapDependencyResponseItem, error)
GetTTL(ctx context.Context, ttlParams *model.GetTTLParams) (*model.GetTTLResponseItem, *model.ApiError)
@ -52,10 +46,12 @@ type Reader interface {
GetErrorForId(ctx context.Context, params *model.GetErrorParams) (*model.ErrorWithSpan, *model.ApiError)
GetErrorForType(ctx context.Context, params *model.GetErrorParams) (*model.ErrorWithSpan, *model.ApiError)
// Search Interfaces
SearchSpansAggregate(ctx context.Context, queryParams *model.SpanSearchAggregatesParams) ([]model.SpanSearchAggregatesResponseItem, error)
SearchSpans(ctx context.Context, query *model.SpanSearchParams) (*[]model.SearchSpansResult, error)
SearchTraces(ctx context.Context, traceID string) (*[]model.SearchSpansResult, error)
// Setter Interfaces
SetTTL(ctx context.Context, ttlParams *model.TTLParams) (*model.SetTTLResponseItem, *model.ApiError)
GetMetricAutocompleteMetricNames(ctx context.Context, matchText string) (*[]string, *model.ApiError)
GetMetricAutocompleteTagKey(ctx context.Context, params *model.MetricAutocompleteTagParams) (*[]string, *model.ApiError)
GetMetricAutocompleteTagValue(ctx context.Context, params *model.MetricAutocompleteTagParams) (*[]string, *model.ApiError)
}

View File

@ -7,25 +7,15 @@ import (
"math"
"net/http"
"strconv"
"strings"
"time"
promModel "github.com/prometheus/common/model"
"go.signoz.io/query-service/constants"
"go.signoz.io/query-service/model"
"go.uber.org/zap"
)
var allowedDimesions = []string{"calls", "duration"}
var allowedFunctions = []string{"count", "ratePerSec", "sum", "avg", "min", "max", "p50", "p90", "p95", "p99"}
var allowedAggregations = map[string][]string{
"calls": {"count", "rate_per_sec"},
"duration": {"avg", "p50", "p95", "p90", "p99", "min", "max", "sum"},
}
func parseUser(r *http.Request) (*model.User, error) {
var user model.User
@ -41,30 +31,27 @@ func parseUser(r *http.Request) (*model.User, error) {
}
func parseGetTopEndpointsRequest(r *http.Request) (*model.GetTopEndpointsParams, error) {
startTime, err := parseTime("start", r)
if err != nil {
return nil, err
}
endTime, err := parseTime("end", r)
var postData *model.GetTopEndpointsParams
err := json.NewDecoder(r.Body).Decode(&postData)
if err != nil {
return nil, err
}
serviceName := r.URL.Query().Get("service")
if len(serviceName) == 0 {
postData.Start, err = parseTimeStr(postData.StartTime, "start")
if err != nil {
return nil, err
}
postData.End, err = parseTimeMinusBufferStr(postData.EndTime, "end")
if err != nil {
return nil, err
}
if len(postData.ServiceName) == 0 {
return nil, errors.New("serviceName param missing in query")
}
getTopEndpointsParams := model.GetTopEndpointsParams{
StartTime: startTime.Format(time.RFC3339Nano),
EndTime: endTime.Format(time.RFC3339Nano),
ServiceName: serviceName,
Start: startTime,
End: endTime,
}
return &getTopEndpointsParams, nil
return postData, nil
}
func parseMetricsTime(s string) (time.Time, error) {
@ -99,7 +86,7 @@ func parseInstantQueryMetricsRequest(r *http.Request) (*model.InstantQueryMetric
var err error
ts, err = parseMetricsTime(t)
if err != nil {
return nil, &model.ApiError{model.ErrorBadData, err}
return nil, &model.ApiError{Typ: model.ErrorBadData, Err: err}
}
} else {
ts = time.Now()
@ -117,32 +104,32 @@ func parseQueryRangeRequest(r *http.Request) (*model.QueryRangeParams, *model.Ap
start, err := parseMetricsTime(r.FormValue("start"))
if err != nil {
return nil, &model.ApiError{model.ErrorBadData, err}
return nil, &model.ApiError{Typ: model.ErrorBadData, Err: err}
}
end, err := parseMetricsTime(r.FormValue("end"))
if err != nil {
return nil, &model.ApiError{model.ErrorBadData, err}
return nil, &model.ApiError{Typ: model.ErrorBadData, Err: err}
}
if end.Before(start) {
err := errors.New("end timestamp must not be before start time")
return nil, &model.ApiError{model.ErrorBadData, err}
return nil, &model.ApiError{Typ: model.ErrorBadData, Err: err}
}
step, err := parseMetricsDuration(r.FormValue("step"))
if err != nil {
return nil, &model.ApiError{model.ErrorBadData, err}
return nil, &model.ApiError{Typ: model.ErrorBadData, Err: err}
}
if step <= 0 {
err := errors.New("zero or negative query resolution step widths are not accepted. Try a positive integer")
return nil, &model.ApiError{model.ErrorBadData, err}
return nil, &model.ApiError{Typ: model.ErrorBadData, Err: err}
}
// For safety, limit the number of returned points per timeseries.
// This is sufficient for 60s resolution for a week or 1h resolution for a year.
if end.Sub(start)/step > 11000 {
err := errors.New("exceeded maximum resolution of 11,000 points per timeseries. Try decreasing the query resolution (?step=XX)")
return nil, &model.ApiError{model.ErrorBadData, err}
return nil, &model.ApiError{Typ: model.ErrorBadData, Err: err}
}
queryRangeParams := model.QueryRangeParams{
@ -192,102 +179,48 @@ func parseGetUsageRequest(r *http.Request) (*model.GetUsageParams, error) {
}
func parseGetServiceExternalRequest(r *http.Request) (*model.GetServiceOverviewParams, error) {
startTime, err := parseTime("start", r)
if err != nil {
return nil, err
}
endTime, err := parseTime("end", r)
if err != nil {
return nil, err
}
stepStr := r.URL.Query().Get("step")
if len(stepStr) == 0 {
return nil, errors.New("step param missing in query")
}
stepInt, err := strconv.Atoi(stepStr)
if err != nil {
return nil, errors.New("step param is not in correct format")
}
serviceName := r.URL.Query().Get("service")
if len(serviceName) == 0 {
return nil, errors.New("serviceName param missing in query")
}
getServiceOverviewParams := model.GetServiceOverviewParams{
Start: startTime,
StartTime: startTime.Format(time.RFC3339Nano),
End: endTime,
EndTime: endTime.Format(time.RFC3339Nano),
ServiceName: serviceName,
Period: fmt.Sprintf("PT%dM", stepInt/60),
StepSeconds: stepInt,
}
return &getServiceOverviewParams, nil
}
func parseGetServiceOverviewRequest(r *http.Request) (*model.GetServiceOverviewParams, error) {
startTime, err := parseTime("start", r)
if err != nil {
return nil, err
}
endTime, err := parseTime("end", r)
var postData *model.GetServiceOverviewParams
err := json.NewDecoder(r.Body).Decode(&postData)
if err != nil {
return nil, err
}
stepStr := r.URL.Query().Get("step")
if len(stepStr) == 0 {
return nil, errors.New("step param missing in query")
}
stepInt, err := strconv.Atoi(stepStr)
postData.Start, err = parseTimeStr(postData.StartTime, "start")
if err != nil {
return nil, errors.New("step param is not in correct format")
return nil, err
}
postData.End, err = parseTimeMinusBufferStr(postData.EndTime, "end")
if err != nil {
return nil, err
}
serviceName := r.URL.Query().Get("service")
if len(serviceName) == 0 {
return nil, errors.New("serviceName param missing in query")
}
getServiceOverviewParams := model.GetServiceOverviewParams{
Start: startTime,
StartTime: startTime.Format(time.RFC3339Nano),
End: endTime,
EndTime: endTime.Format(time.RFC3339Nano),
ServiceName: serviceName,
Period: fmt.Sprintf("PT%dM", stepInt/60),
StepSeconds: stepInt,
}
return &getServiceOverviewParams, nil
postData.Period = fmt.Sprintf("PT%dM", postData.StepSeconds/60)
return postData, nil
}
func parseGetServicesRequest(r *http.Request) (*model.GetServicesParams, error) {
startTime, err := parseTime("start", r)
if err != nil {
return nil, err
}
endTime, err := parseTime("end", r)
var postData *model.GetServicesParams
err := json.NewDecoder(r.Body).Decode(&postData)
if err != nil {
return nil, err
}
getServicesParams := model.GetServicesParams{
Start: startTime,
StartTime: startTime.Format(time.RFC3339Nano),
End: endTime,
EndTime: endTime.Format(time.RFC3339Nano),
Period: int(endTime.Unix() - startTime.Unix()),
postData.Start, err = parseTimeStr(postData.StartTime, "start")
if err != nil {
return nil, err
}
postData.End, err = parseTimeMinusBufferStr(postData.EndTime, "end")
if err != nil {
return nil, err
}
return &getServicesParams, nil
postData.Period = int(postData.End.Unix() - postData.Start.Unix())
return postData, nil
}
func DoesExistInSlice(item string, list []string) bool {
@ -299,189 +232,6 @@ func DoesExistInSlice(item string, list []string) bool {
return false
}
func parseSearchSpanAggregatesRequest(r *http.Request) (*model.SpanSearchAggregatesParams, error) {
startTime, err := parseTime("start", r)
if err != nil {
return nil, err
}
endTime, err := parseTime("end", r)
if err != nil {
return nil, err
}
startTimeStr := startTime.Format(time.RFC3339Nano)
endTimeStr := endTime.Format(time.RFC3339Nano)
// fmt.Println(startTimeStr)
stepStr := r.URL.Query().Get("step")
if len(stepStr) == 0 {
return nil, errors.New("step param missing in query")
}
stepInt, err := strconv.Atoi(stepStr)
if err != nil {
return nil, errors.New("step param is not in correct format")
}
granPeriod := fmt.Sprintf("PT%dM", stepInt/60)
dimension := r.URL.Query().Get("dimension")
if len(dimension) == 0 {
return nil, errors.New("dimension param missing in query")
} else {
if !DoesExistInSlice(dimension, allowedDimesions) {
return nil, errors.New(fmt.Sprintf("given dimension: %s is not allowed in query", dimension))
}
}
aggregationOption := r.URL.Query().Get("aggregation_option")
if len(aggregationOption) == 0 {
return nil, errors.New("Aggregation Option missing in query params")
} else {
if !DoesExistInSlice(aggregationOption, allowedAggregations[dimension]) {
return nil, errors.New(fmt.Sprintf("given aggregation option: %s is not allowed with dimension: %s", aggregationOption, dimension))
}
}
params := &model.SpanSearchAggregatesParams{
Start: startTime,
End: endTime,
Intervals: fmt.Sprintf("%s/%s", startTimeStr, endTimeStr),
GranOrigin: startTimeStr,
GranPeriod: granPeriod,
StepSeconds: stepInt,
Dimension: dimension,
AggregationOption: aggregationOption,
}
serviceName := r.URL.Query().Get("service")
if len(serviceName) != 0 {
// return nil, errors.New("serviceName param missing in query")
params.ServiceName = serviceName
}
operationName := r.URL.Query().Get("operation")
if len(operationName) != 0 {
params.OperationName = operationName
// Escaping new line chars to avoid CWE-117
operationName = strings.Replace(operationName, "\n", "", -1)
operationName = strings.Replace(operationName, "\r", "", -1)
zap.S().Debug("Operation Name: ", operationName)
}
kind := r.URL.Query().Get("kind")
if len(kind) != 0 {
params.Kind = kind
// Escaping new line chars to avoid CWE-117
kind = strings.Replace(kind, "\n", "", -1)
kind = strings.Replace(kind, "\r", "", -1)
zap.S().Debug("Kind: ", kind)
}
minDuration, err := parseTimestamp("minDuration", r)
if err == nil {
params.MinDuration = *minDuration
}
maxDuration, err := parseTimestamp("maxDuration", r)
if err == nil {
params.MaxDuration = *maxDuration
}
tags, err := parseTags("tags", r)
if err != nil {
return nil, err
}
if len(*tags) != 0 {
params.Tags = *tags
}
return params, nil
}
func parseSpanSearchRequest(r *http.Request) (*model.SpanSearchParams, error) {
startTime, err := parseTime("start", r)
if err != nil {
return nil, err
}
endTime, err := parseTimeMinusBuffer("end", r)
if err != nil {
return nil, err
}
startTimeStr := startTime.Format(time.RFC3339Nano)
endTimeStr := endTime.Format(time.RFC3339Nano)
// fmt.Println(startTimeStr)
params := &model.SpanSearchParams{
Intervals: fmt.Sprintf("%s/%s", startTimeStr, endTimeStr),
Start: startTime,
End: endTime,
Limit: 100,
Order: "descending",
}
serviceName := r.URL.Query().Get("service")
if len(serviceName) != 0 {
// return nil, errors.New("serviceName param missing in query")
params.ServiceName = serviceName
}
operationName := r.URL.Query().Get("operation")
if len(operationName) != 0 {
params.OperationName = operationName
// Escaping new line chars to avoid CWE-117
operationName = strings.Replace(operationName, "\n", "", -1)
operationName = strings.Replace(operationName, "\r", "", -1)
zap.S().Debug("Operation Name: ", operationName)
}
kind := r.URL.Query().Get("kind")
if len(kind) != 0 {
params.Kind = kind
// Escaping new line chars to avoid CWE-117
kind = strings.Replace(kind, "\n", "", -1)
kind = strings.Replace(kind, "\r", "", -1)
zap.S().Debug("Kind: ", kind)
}
minDuration, err := parseTimestamp("minDuration", r)
if err == nil {
params.MinDuration = *minDuration
}
maxDuration, err := parseTimestamp("maxDuration", r)
if err == nil {
params.MaxDuration = *maxDuration
}
limitStr := r.URL.Query().Get("limit")
if len(limitStr) != 0 {
limit, err := strconv.ParseInt(limitStr, 10, 64)
if err != nil {
return nil, errors.New("Limit param is not in correct format")
}
params.Limit = limit
} else {
params.Limit = 100
}
offsetStr := r.URL.Query().Get("offset")
if len(offsetStr) != 0 {
offset, err := strconv.ParseInt(offsetStr, 10, 64)
if err != nil {
return nil, errors.New("Offset param is not in correct format")
}
params.Offset = offset
}
tags, err := parseTags("tags", r)
if err != nil {
return nil, err
}
if len(*tags) != 0 {
params.Tags = *tags
}
return params, nil
}
func parseSpanFilterRequestBody(r *http.Request) (*model.SpanFilterParams, error) {
var postData *model.SpanFilterParams
@ -522,7 +272,7 @@ func parseFilteredSpansRequest(r *http.Request) (*model.GetFilteredSpansParams,
}
if postData.Limit == 0 {
postData.Limit = 100
postData.Limit = 10
}
return postData, nil
@ -694,96 +444,6 @@ func parseErrorsRequest(r *http.Request) (*model.GetErrorsParams, error) {
return params, nil
}
func fetchArrayValues(param string, r *http.Request) []string {
valueStr := r.URL.Query().Get(param)
var values []string
if len(valueStr) == 0 {
return values
}
err := json.Unmarshal([]byte(valueStr), &values)
if err != nil {
zap.S().Error("Error in parsing service params", zap.Error(err))
}
return values
}
func parseTags(param string, r *http.Request) (*[]model.TagQuery, error) {
tags := new([]model.TagQuery)
tagsStr := r.URL.Query().Get(param)
if len(tagsStr) == 0 {
return tags, nil
}
err := json.Unmarshal([]byte(tagsStr), tags)
if err != nil {
zap.S().Error("Error in parsig tags", zap.Error(err))
return nil, fmt.Errorf("error in parsing %s ", param)
}
// zap.S().Info("Tags: ", *tags)
return tags, nil
}
func parseTagsV2(param string, r *http.Request) (*[]model.TagQueryV2, error) {
tags := new([]model.TagQueryV2)
tagsStr := r.URL.Query().Get(param)
if len(tagsStr) == 0 {
return tags, nil
}
err := json.Unmarshal([]byte(tagsStr), tags)
if err != nil {
zap.S().Error("Error in parsig tags", zap.Error(err))
return nil, fmt.Errorf("error in parsing %s ", param)
}
// zap.S().Info("Tags: ", *tags)
return tags, nil
}
func parseApplicationPercentileRequest(r *http.Request) (*model.ApplicationPercentileParams, error) {
startTime, err := parseTime("start", r)
if err != nil {
return nil, err
}
endTime, err := parseTime("end", r)
if err != nil {
return nil, err
}
stepStr := r.URL.Query().Get("step")
if len(stepStr) == 0 {
return nil, errors.New("step param missing in query")
}
serviceName := r.URL.Query().Get("service")
if len(serviceName) == 0 {
return nil, errors.New("serviceName param missing in query")
}
startTimeStr := startTime.Format(time.RFC3339Nano)
endTimeStr := endTime.Format(time.RFC3339Nano)
params := &model.ApplicationPercentileParams{
ServiceName: serviceName,
GranOrigin: startTimeStr,
Intervals: fmt.Sprintf("%s/%s", startTimeStr, endTimeStr),
}
stepInt, err := strconv.Atoi(stepStr)
if err != nil {
return nil, errors.New("step param is not in correct format")
}
params.SetGranPeriod(stepInt)
return params, nil
}
func parseTimeStr(timeStr string, param string) (*time.Time, error) {
if len(timeStr) == 0 {
@ -864,25 +524,6 @@ func parseTimeMinusBuffer(param string, r *http.Request) (*time.Time, error) {
}
func parseTimestamp(param string, r *http.Request) (*string, error) {
timeStr := r.URL.Query().Get(param)
if len(timeStr) == 0 {
return nil, fmt.Errorf("%s param missing in query", param)
}
// timeUnix, err := strconv.ParseInt(timeStr, 10, 64)
// if err != nil || len(timeStr) == 0 {
// return nil, fmt.Errorf("%s param is not in correct timestamp format", param)
// }
return &timeStr, nil
}
func parseSetRulesRequest(r *http.Request) (string, *model.ApiError) {
return "", nil
}
func parseTTLParams(r *http.Request) (*model.TTLParams, error) {
// make sure either of the query params are present
@ -921,9 +562,9 @@ func parseTTLParams(r *http.Request) (*model.TTLParams, error) {
return &model.TTLParams{
Type: typeTTL,
DelDuration: durationParsed.Seconds(),
DelDuration: int64(durationParsed.Seconds()),
ColdStorageVolume: coldStorage,
ToColdStorageDuration: toColdParsed.Seconds(),
ToColdStorageDuration: int64(toColdParsed.Seconds()),
}, nil
}

View File

@ -0,0 +1,56 @@
package parser
import (
"encoding/json"
"fmt"
"net/http"
"go.signoz.io/query-service/model"
)
func ParseMetricQueryRangeParams(r *http.Request) (*model.QueryRangeParamsV2, *model.ApiError) {
var postData *model.QueryRangeParamsV2
err := json.NewDecoder(r.Body).Decode(&postData)
if err != nil {
return nil, &model.ApiError{Typ: model.ErrorBadData, Err: err}
}
return nil, nil
}
func ParseMetricAutocompleteTagParams(r *http.Request) (*model.MetricAutocompleteTagParams, *model.ApiError) {
metricName := r.URL.Query().Get("metricName")
if len(metricName) == 0 {
err := fmt.Errorf("metricName not present in params")
return nil, &model.ApiError{Typ: model.ErrorBadData, Err: err}
}
tagsStr := r.URL.Query().Get("tags")
// fmt.Println(tagsStr)
// parsing tags
var tags map[string]string
if tagsStr != "" && len(tagsStr) != 0 {
err := json.Unmarshal([]byte(tagsStr), &tags)
if err != nil {
return nil, &model.ApiError{Typ: model.ErrorBadData, Err: fmt.Errorf("unable to parse tags in params: %v", err)}
}
}
matchText := r.URL.Query().Get("match")
tagKey := r.URL.Query().Get("tagKey")
metricAutocompleteTagParams := &model.MetricAutocompleteTagParams{
MetricName: metricName,
MetricTags: tags,
Match: matchText,
TagKey: tagKey,
}
return metricAutocompleteTagParams, nil
}

View File

@ -1,6 +1,7 @@
package app
import (
"context"
"fmt"
"net"
"net/http"
@ -14,7 +15,6 @@ import (
"github.com/soheilhy/cmux"
"go.signoz.io/query-service/app/clickhouseReader"
"go.signoz.io/query-service/app/dashboards"
"go.signoz.io/query-service/app/druidReader"
"go.signoz.io/query-service/constants"
"go.signoz.io/query-service/dao"
"go.signoz.io/query-service/healthcheck"
@ -103,7 +103,7 @@ func (s *Server) createHTTPServer() (*http.Server, error) {
storage := os.Getenv("STORAGE")
if storage == "druid" {
zap.S().Info("Using Apache Druid as datastore ...")
reader = druidReader.NewReader(localDB)
// reader = druidReader.NewReader(localDB)
} else if storage == "clickhouse" {
zap.S().Info("Using ClickHouse as datastore ...")
clickhouseReader := clickhouseReader.NewReader(localDB)
@ -125,10 +125,12 @@ func (s *Server) createHTTPServer() (*http.Server, error) {
r := NewRouter()
r.Use(setTimeoutMiddleware)
r.Use(s.analyticsMiddleware)
r.Use(loggingMiddleware)
apiHandler.RegisterRoutes(r)
apiHandler.RegisterMetricsRoutes(r)
c := cors.New(cors.Options{
AllowedOrigins: []string{"*"},
@ -171,6 +173,16 @@ func (s *Server) analyticsMiddleware(next http.Handler) http.Handler {
})
}
func setTimeoutMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx, cancel := context.WithTimeout(r.Context(), constants.ContextTimeout*time.Second)
defer cancel()
r = r.WithContext(ctx)
next.ServeHTTP(w, r)
})
}
// initListener initialises listeners of the server
func (s *Server) initListener() (cmux.CMux, error) {
if s.separatePorts { // use separate ports and listeners each for gRPC and HTTP requests

View File

@ -7,8 +7,6 @@ import (
const HTTPHostPort = "0.0.0.0:8080"
var DruidClientUrl = os.Getenv("DruidClientUrl")
var DruidDatasource = os.Getenv("DruidDatasource")
var DEFAULT_TELEMETRY_ANONYMOUS = false
func IsTelemetryEnabled() bool {
@ -45,6 +43,17 @@ const (
Component = "component"
OperationDB = "name"
OperationRequest = "operation"
Status = "status"
Duration = "duration"
DBName = "dbName"
DBOperation = "dbOperation"
DBSystem = "dbSystem"
MsgSystem = "msgSystem"
MsgOperation = "msgOperation"
Timestamp = "timestamp"
Descending = "descending"
Ascending = "ascending"
ContextTimeout = 60 // seconds
)

View File

@ -1,9 +1,10 @@
package constants
import (
. "github.com/smartystreets/goconvey/convey"
"os"
"testing"
. "github.com/smartystreets/goconvey/convey"
)
func TestGetAlertManagerApiPrefix(t *testing.T) {

View File

@ -32,7 +32,7 @@ func InitDB(dataSourceName string) (*ModelDaoSqlite, error) {
_, err = db.Exec(table_schema)
if err != nil {
return nil, fmt.Errorf("Error in creating user_preferences table: ", err.Error())
return nil, fmt.Errorf("Error in creating user_preferences table: %s", err.Error())
}
mds := &ModelDaoSqlite{db: db}

View File

@ -1,100 +0,0 @@
package druidQuery
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"time"
"go.uber.org/zap"
)
const (
SQL_ENDPOINT = "/druid/v2/sql"
)
type SqlClient struct {
Url string
EndPoint string
Timeout time.Duration
Debug bool
LastRequest string
LastResponse string
}
type SqlQuery struct {
Query string `json:"query"`
Header bool `json:"header"`
ResultFormat string `json:"resultFormat"`
}
func (c *SqlClient) Query(sql string, resultFormat string) ([]byte, error) {
query := SqlQuery{
Query: sql,
Header: true,
ResultFormat: resultFormat,
}
reqJson, err := json.Marshal(query)
// log request made to druid
zap.S().Info(string(reqJson))
result, err := c.QueryRaw(reqJson)
if err != nil {
return []byte("Error"), err
}
return result, nil
}
func (c *SqlClient) QueryRaw(req []byte) (result []byte, err error) {
if c.EndPoint == "" {
c.EndPoint = SQL_ENDPOINT
}
endPoint := c.EndPoint
if c.Debug {
endPoint += "?pretty"
c.LastRequest = string(req)
}
if err != nil {
return
}
// By default, use 60 second timeout unless specified otherwise
// by the caller
clientTimeout := 60 * time.Second
if c.Timeout != 0 {
clientTimeout = c.Timeout
}
httpClient := &http.Client{
Timeout: clientTimeout,
}
resp, err := httpClient.Post(c.Url+endPoint, "application/json", bytes.NewBuffer(req))
if err != nil {
return
}
defer func() {
resp.Body.Close()
}()
result, err = ioutil.ReadAll(resp.Body)
if err != nil {
return
}
if c.Debug {
c.LastResponse = string(result)
}
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("%s: %s", resp.Status, string(result))
}
return
}

View File

@ -1,571 +0,0 @@
package druidQuery
import (
"encoding/json"
"fmt"
"strconv"
"time"
"go.signoz.io/query-service/constants"
"go.signoz.io/query-service/model"
"go.uber.org/zap"
)
func GetOperations(client *SqlClient, serviceName string) (*[]string, error) {
sqlQuery := fmt.Sprintf(`SELECT DISTINCT(Name) FROM %s WHERE ServiceName='%s' AND __time > CURRENT_TIMESTAMP - INTERVAL '1' DAY`, constants.DruidDatasource, serviceName)
// zap.S().Debug(sqlQuery)
response, err := client.Query(sqlQuery, "array")
if err != nil {
zap.S().Error(sqlQuery, err)
return nil, fmt.Errorf("Something went wrong in druid query")
}
// zap.S().Info(string(response))
res := new([][]string)
err = json.Unmarshal(response, res)
if err != nil {
zap.S().Error(err)
return nil, fmt.Errorf("Error in unmarshalling response from druid")
}
var getOperationsReponse []string
for _, item := range *res {
getOperationsReponse = append(getOperationsReponse, item[0])
}
getOperationsReponse = getOperationsReponse[1:]
return &getOperationsReponse, nil
}
func GetServicesList(client *SqlClient) (*[]string, error) {
sqlQuery := fmt.Sprintf(`SELECT DISTINCT(ServiceName) FROM %s WHERE __time > CURRENT_TIMESTAMP - INTERVAL '1' DAY`, constants.DruidDatasource)
// zap.S().Debug(sqlQuery)
response, err := client.Query(sqlQuery, "array")
if err != nil {
zap.S().Error(sqlQuery, err)
return nil, fmt.Errorf("Something went wrong in druid query")
}
// zap.S().Info(string(response))
res := new([][]string)
err = json.Unmarshal(response, res)
if err != nil {
zap.S().Error(err)
return nil, fmt.Errorf("Error in unmarshalling response from druid")
}
var servicesListReponse []string
for _, item := range *res {
servicesListReponse = append(servicesListReponse, item[0])
}
servicesListReponse = servicesListReponse[1:]
return &servicesListReponse, nil
}
func GetTags(client *SqlClient, serviceName string) (*[]model.TagItem, error) {
var sqlQuery string
if len(serviceName) != 0 {
sqlQuery = fmt.Sprintf(`SELECT TagsKeys as tagKeys, Count(TagsKeys) as "tagCount" FROM %s WHERE "ServiceName"='%s' AND "__time" > CURRENT_TIMESTAMP - INTERVAL '1' DAY GROUP BY TagsKeys ORDER BY tagCount DESC LIMIT 100`, constants.DruidDatasource, serviceName)
} else {
sqlQuery = fmt.Sprintf(`SELECT TagsKeys as tagKeys, Count(TagsKeys) as "tagCount" FROM %s WHERE "__time" > CURRENT_TIMESTAMP - INTERVAL '1' DAY GROUP BY TagsKeys ORDER BY tagCount DESC LIMIT 100`, constants.DruidDatasource)
}
// zap.S().Debug(sqlQuery)
response, err := client.Query(sqlQuery, "object")
if err != nil {
zap.S().Error(sqlQuery, err)
return nil, fmt.Errorf("Something went wrong in druid query")
}
// zap.S().Info(string(response))
res := new([]model.TagItem)
err = json.Unmarshal(response, res)
if err != nil {
zap.S().Error(err)
return nil, fmt.Errorf("Error in unmarshalling response from druid")
}
tagResponse := (*res)[1:]
return &tagResponse, nil
}
func GetTopEndpoints(client *SqlClient, query *model.GetTopEndpointsParams) (*[]model.TopEndpointsItem, error) {
sqlQuery := fmt.Sprintf(`SELECT APPROX_QUANTILE_DS("QuantileDuration", 0.5) as p50, APPROX_QUANTILE_DS("QuantileDuration", 0.95) as p95, APPROX_QUANTILE_DS("QuantileDuration", 0.99) as p99, COUNT(SpanId) as numCalls, Name FROM "%s" WHERE "__time" >= '%s' AND "__time" <= '%s' AND "Kind"='2' and "ServiceName"='%s' GROUP BY Name`, constants.DruidDatasource, query.StartTime, query.EndTime, query.ServiceName)
// zap.S().Debug(sqlQuery)
response, err := client.Query(sqlQuery, "object")
if err != nil {
zap.S().Error(query, err)
return nil, fmt.Errorf("Something went wrong in druid query")
}
// zap.S().Info(string(response))
res := new([]model.TopEndpointsItem)
err = json.Unmarshal(response, res)
if err != nil {
zap.S().Error(err)
return nil, fmt.Errorf("Error in unmarshalling response from druid")
}
topEnpointsResponse := (*res)[1:]
return &topEnpointsResponse, nil
}
func GetUsage(client *SqlClient, query *model.GetUsageParams) (*[]model.UsageItem, error) {
var sqlQuery string
if len(query.ServiceName) != 0 {
sqlQuery = fmt.Sprintf(`SELECT TIME_FLOOR(__time, '%s') as "time", COUNT(SpanId) as "count" FROM "%s" WHERE "__time" >= '%s' and "__time" <= '%s' and "ServiceName"='%s' GROUP BY TIME_FLOOR(__time, '%s')`, query.Period, constants.DruidDatasource, query.StartTime, query.EndTime, query.ServiceName, query.Period)
} else {
sqlQuery = fmt.Sprintf(`SELECT TIME_FLOOR(__time, '%s') as "time", COUNT(SpanId) as "count" FROM "%s" WHERE "__time" >= '%s' and "__time" <= '%s' GROUP BY TIME_FLOOR(__time, '%s')`, query.Period, constants.DruidDatasource, query.StartTime, query.EndTime, query.Period)
}
// zap.S().Debug(sqlQuery)
response, err := client.Query(sqlQuery, "object")
if err != nil {
zap.S().Error(query, err)
return nil, fmt.Errorf("Something went wrong in druid query")
}
// zap.S().Info(string(response))
res := new([]model.UsageItem)
err = json.Unmarshal(response, res)
if err != nil {
zap.S().Error(err)
return nil, fmt.Errorf("Error in unmarshalling response from druid")
}
for i, _ := range *res {
timeObj, _ := time.Parse(time.RFC3339Nano, (*res)[i].Time)
(*res)[i].Timestamp = int64(timeObj.UnixNano())
(*res)[i].Time = ""
}
usageResponse := (*res)[1:]
return &usageResponse, nil
}
func GetServiceExternalAvgDuration(client *SqlClient, query *model.GetServiceOverviewParams) (*[]model.ServiceExternalItem, error) {
sqlQuery := fmt.Sprintf(`SELECT TIME_FLOOR(__time, '%s') as "time", AVG(DurationNano) as "avgDuration" FROM %s WHERE ServiceName='%s' AND Kind='3' AND ExternalHttpUrl != '' AND "__time" >= '%s' AND "__time" <= '%s'
GROUP BY TIME_FLOOR(__time, '%s')`, query.Period, constants.DruidDatasource, query.ServiceName, query.StartTime, query.EndTime, query.Period)
// zap.S().Debug(sqlQuery)
response, err := client.Query(sqlQuery, "object")
if err != nil {
zap.S().Error(query, err)
return nil, fmt.Errorf("Something went wrong in druid query")
}
// responseStr := string(response)
// zap.S().Info(responseStr)
res := new([]model.ServiceExternalItem)
err = json.Unmarshal(response, res)
if err != nil {
zap.S().Error(err)
return nil, fmt.Errorf("Error in unmarshalling response from druid")
}
for i, _ := range *res {
timeObj, _ := time.Parse(time.RFC3339Nano, (*res)[i].Time)
(*res)[i].Timestamp = int64(timeObj.UnixNano())
(*res)[i].Time = ""
(*res)[i].CallRate = float32((*res)[i].NumCalls) / float32(query.StepSeconds)
}
servicesExternalResponse := (*res)[1:]
return &servicesExternalResponse, nil
}
func GetServiceExternalErrors(client *SqlClient, query *model.GetServiceOverviewParams) (*[]model.ServiceExternalItem, error) {
sqlQuery := fmt.Sprintf(`SELECT TIME_FLOOR(__time, '%s') as "time", COUNT(SpanId) as "numCalls", ExternalHttpUrl as externalHttpUrl FROM %s WHERE ServiceName='%s' AND Kind='3' AND ExternalHttpUrl != '' AND (StatusCode >= 500 OR StatusCode=2) AND "__time" >= '%s' AND "__time" <= '%s'
GROUP BY TIME_FLOOR(__time, '%s'), ExternalHttpUrl`, query.Period, constants.DruidDatasource, query.ServiceName, query.StartTime, query.EndTime, query.Period)
// zap.S().Debug(sqlQuery)
response, err := client.Query(sqlQuery, "object")
if err != nil {
zap.S().Error(query, err)
return nil, fmt.Errorf("Something went wrong in druid query")
}
// responseStr := string(response)
// zap.S().Info(responseStr)
res := new([]model.ServiceExternalItem)
err = json.Unmarshal(response, res)
if err != nil {
zap.S().Error(err)
return nil, fmt.Errorf("Error in unmarshalling response from druid")
}
sqlQuery = fmt.Sprintf(`SELECT TIME_FLOOR(__time, '%s') as "time", COUNT(SpanId) as "numCalls", ExternalHttpUrl as externalHttpUrl FROM %s WHERE ServiceName='%s' AND Kind='3' AND ExternalHttpUrl != '' AND "__time" >= '%s' AND "__time" <= '%s'
GROUP BY TIME_FLOOR(__time, '%s'), ExternalHttpUrl`, query.Period, constants.DruidDatasource, query.ServiceName, query.StartTime, query.EndTime, query.Period)
// zap.S().Debug(sqlQuery)
responseTotal, err := client.Query(sqlQuery, "object")
if err != nil {
zap.S().Error(query, err)
return nil, fmt.Errorf("Something went wrong in druid query")
}
// responseStr := string(response)
// zap.S().Info(responseStr)
resTotal := new([]model.ServiceExternalItem)
err = json.Unmarshal(responseTotal, resTotal)
if err != nil {
zap.S().Error(err)
return nil, fmt.Errorf("Error in unmarshalling response from druid")
}
m := make(map[string]int)
for j, _ := range *res {
timeObj, _ := time.Parse(time.RFC3339Nano, (*res)[j].Time)
m[strconv.FormatInt(timeObj.UnixNano(), 10)+"-"+(*res)[j].ExternalHttpUrl] = (*res)[j].NumCalls
}
for i, _ := range *resTotal {
timeObj, _ := time.Parse(time.RFC3339Nano, (*resTotal)[i].Time)
(*resTotal)[i].Timestamp = int64(timeObj.UnixNano())
(*resTotal)[i].Time = ""
(*resTotal)[i].CallRate = float32((*resTotal)[i].NumCalls) / float32(query.StepSeconds)
if val, ok := m[strconv.FormatInt((*resTotal)[i].Timestamp, 10)+"-"+(*resTotal)[i].ExternalHttpUrl]; ok {
(*resTotal)[i].NumErrors = val
(*resTotal)[i].ErrorRate = float32((*resTotal)[i].NumErrors) * 100 / float32((*resTotal)[i].NumCalls)
}
(*resTotal)[i].CallRate = 0
(*resTotal)[i].NumCalls = 0
}
servicesExternalResponse := (*resTotal)[1:]
return &servicesExternalResponse, nil
}
func GetServiceExternal(client *SqlClient, query *model.GetServiceOverviewParams) (*[]model.ServiceExternalItem, error) {
sqlQuery := fmt.Sprintf(`SELECT TIME_FLOOR(__time, '%s') as "time", AVG(DurationNano) as "avgDuration", COUNT(SpanId) as "numCalls", ExternalHttpUrl as externalHttpUrl FROM %s WHERE ServiceName='%s' AND Kind='3' AND ExternalHttpUrl != ''
AND "__time" >= '%s' AND "__time" <= '%s'
GROUP BY TIME_FLOOR(__time, '%s'), ExternalHttpUrl`, query.Period, constants.DruidDatasource, query.ServiceName, query.StartTime, query.EndTime, query.Period)
// zap.S().Debug(sqlQuery)
response, err := client.Query(sqlQuery, "object")
if err != nil {
zap.S().Error(query, err)
return nil, fmt.Errorf("Something went wrong in druid query")
}
// responseStr := string(response)
// zap.S().Info(responseStr)
res := new([]model.ServiceExternalItem)
err = json.Unmarshal(response, res)
if err != nil {
zap.S().Error(err)
return nil, fmt.Errorf("Error in unmarshalling response from druid")
}
for i, _ := range *res {
timeObj, _ := time.Parse(time.RFC3339Nano, (*res)[i].Time)
(*res)[i].Timestamp = int64(timeObj.UnixNano())
(*res)[i].Time = ""
(*res)[i].CallRate = float32((*res)[i].NumCalls) / float32(query.StepSeconds)
}
servicesExternalResponse := (*res)[1:]
return &servicesExternalResponse, nil
}
func GetServiceDBOverview(client *SqlClient, query *model.GetServiceOverviewParams) (*[]model.ServiceDBOverviewItem, error) {
sqlQuery := fmt.Sprintf(`SELECT TIME_FLOOR(__time, '%s') as "time", AVG(DurationNano) as "avgDuration", COUNT(SpanId) as "numCalls", DBSystem as "dbSystem" FROM %s WHERE ServiceName='%s' AND Kind='3' AND DBName IS NOT NULL
AND "__time" >= '%s' AND "__time" <= '%s'
GROUP BY TIME_FLOOR(__time, '%s'), DBSystem`, query.Period, constants.DruidDatasource, query.ServiceName, query.StartTime, query.EndTime, query.Period)
// zap.S().Debug(sqlQuery)
response, err := client.Query(sqlQuery, "object")
if err != nil {
zap.S().Error(query, err)
return nil, fmt.Errorf("Something went wrong in druid query")
}
// responseStr := string(response)
// zap.S().Info(responseStr)
res := new([]model.ServiceDBOverviewItem)
err = json.Unmarshal(response, res)
if err != nil {
zap.S().Error(err)
return nil, fmt.Errorf("Error in unmarshalling response from druid")
}
for i, _ := range *res {
timeObj, _ := time.Parse(time.RFC3339Nano, (*res)[i].Time)
(*res)[i].Timestamp = int64(timeObj.UnixNano())
(*res)[i].Time = ""
(*res)[i].CallRate = float32((*res)[i].NumCalls) / float32(query.StepSeconds)
}
servicesDBOverviewResponse := (*res)[1:]
return &servicesDBOverviewResponse, nil
}
func GetServiceOverview(client *SqlClient, query *model.GetServiceOverviewParams) (*[]model.ServiceOverviewItem, error) {
sqlQuery := fmt.Sprintf(`SELECT TIME_FLOOR(__time, '%s') as "time", APPROX_QUANTILE_DS("QuantileDuration", 0.5) as p50, APPROX_QUANTILE_DS("QuantileDuration", 0.95) as p95,
APPROX_QUANTILE_DS("QuantileDuration", 0.99) as p99, COUNT("SpanId") as "numCalls" FROM "%s" WHERE "__time" >= '%s' and "__time" <= '%s' and "Kind"='2' and "ServiceName"='%s' GROUP BY TIME_FLOOR(__time, '%s') `, query.Period, constants.DruidDatasource, query.StartTime, query.EndTime, query.ServiceName, query.Period)
// zap.S().Debug(sqlQuery)
response, err := client.Query(sqlQuery, "object")
if err != nil {
zap.S().Error(query, err)
return nil, fmt.Errorf("Something went wrong in druid query")
}
// zap.S().Info(string(response))
res := new([]model.ServiceOverviewItem)
err = json.Unmarshal(response, res)
if err != nil {
zap.S().Error(err)
return nil, fmt.Errorf("Error in unmarshalling response from druid")
}
sqlQuery = fmt.Sprintf(`SELECT TIME_FLOOR(__time, '%s') as "time", COUNT("SpanId") as "numErrors" FROM "%s" WHERE "__time" >= '%s' and "__time" <= '%s' and "Kind"='2' and "ServiceName"='%s' and ("StatusCode">=500 or "StatusCode"=2) GROUP BY TIME_FLOOR(__time, '%s') `, query.Period, constants.DruidDatasource, query.StartTime, query.EndTime, query.ServiceName, query.Period)
// zap.S().Debug(sqlQuery)
responseError, err := client.Query(sqlQuery, "object")
if err != nil {
zap.S().Error(query, err)
return nil, fmt.Errorf("Something went wrong in druid query")
}
// zap.S().Info(string(response))
resError := new([]model.ServiceErrorItem)
err = json.Unmarshal(responseError, resError)
if err != nil {
zap.S().Error(err)
return nil, fmt.Errorf("Error in unmarshalling response from druid")
}
m := make(map[int64]int)
for j, _ := range *resError {
timeObj, _ := time.Parse(time.RFC3339Nano, (*resError)[j].Time)
m[int64(timeObj.UnixNano())] = (*resError)[j].NumErrors
}
for i, _ := range *res {
timeObj, _ := time.Parse(time.RFC3339Nano, (*res)[i].Time)
(*res)[i].Timestamp = int64(timeObj.UnixNano())
(*res)[i].Time = ""
if val, ok := m[(*res)[i].Timestamp]; ok {
(*res)[i].NumErrors = val
}
(*res)[i].ErrorRate = float32((*res)[i].NumErrors) * 100 / float32((*res)[i].NumCalls)
(*res)[i].CallRate = float32((*res)[i].NumCalls) / float32(query.StepSeconds)
}
servicesOverviewResponse := (*res)[1:]
return &servicesOverviewResponse, nil
}
func GetServices(client *SqlClient, query *model.GetServicesParams) (*[]model.ServiceItem, error) {
sqlQuery := fmt.Sprintf(`SELECT APPROX_QUANTILE_DS("QuantileDuration", 0.99) as "p99", AVG("DurationNano") as "avgDuration", COUNT(SpanId) as numCalls, "ServiceName" as "serviceName" FROM %s WHERE "__time" >= '%s' and "__time" <= '%s' and "Kind"='2' GROUP BY "ServiceName" ORDER BY "p99" DESC`, constants.DruidDatasource, query.StartTime, query.EndTime)
response, err := client.Query(sqlQuery, "object")
// zap.S().Debug(sqlQuery)
if err != nil {
zap.S().Error(query, err)
return nil, fmt.Errorf("Something went wrong in druid query")
}
// zap.S().Info(string(response))
res := new([]model.ServiceItem)
err = json.Unmarshal(response, res)
if err != nil {
zap.S().Error(err)
return nil, fmt.Errorf("Error in unmarshalling response from druid")
}
////////////////// Below block gets 5xx of services
sqlQuery = fmt.Sprintf(`SELECT COUNT(SpanId) as numErrors, "ServiceName" as "serviceName" FROM %s WHERE "__time" >= '%s' and "__time" <= '%s' and "Kind"='2' and ("StatusCode">=500 or "StatusCode"=2) GROUP BY "ServiceName"`, constants.DruidDatasource, query.StartTime, query.EndTime)
responseError, err := client.Query(sqlQuery, "object")
zap.S().Debug(sqlQuery)
if err != nil {
zap.S().Error(query, err)
return nil, fmt.Errorf("Something went wrong in druid query")
}
// zap.S().Info(string(response))
resError := new([]model.ServiceListErrorItem)
err = json.Unmarshal(responseError, resError)
if err != nil {
zap.S().Error(err)
return nil, fmt.Errorf("Error in unmarshalling response from druid")
}
m := make(map[string]int)
for j, _ := range *resError {
m[(*resError)[j].ServiceName] = (*resError)[j].NumErrors
}
///////////////////////////////////////////
////////////////// Below block gets 4xx of services
sqlQuery = fmt.Sprintf(`SELECT COUNT(SpanId) as num4xx, "ServiceName" as "serviceName" FROM %s WHERE "__time" >= '%s' and "__time" <= '%s' and "Kind"='2' and "StatusCode">=400 and "StatusCode" < 500 GROUP BY "ServiceName"`, constants.DruidDatasource, query.StartTime, query.EndTime)
response4xx, err := client.Query(sqlQuery, "object")
// zap.S().Debug(sqlQuery)
if err != nil {
zap.S().Error(query, err)
return nil, fmt.Errorf("Something went wrong in druid query")
}
// zap.S().Info(string(response))
res4xx := new([]model.ServiceListErrorItem)
err = json.Unmarshal(response4xx, res4xx)
if err != nil {
zap.S().Error(err)
return nil, fmt.Errorf("Error in unmarshalling response from druid")
}
m4xx := make(map[string]int)
for j, _ := range *res4xx {
m4xx[(*res4xx)[j].ServiceName] = (*res4xx)[j].Num4xx
}
///////////////////////////////////////////
for i, _ := range *res {
if val, ok := m[(*res)[i].ServiceName]; ok {
(*res)[i].NumErrors = val
}
if val, ok := m4xx[(*res)[i].ServiceName]; ok {
(*res)[i].Num4XX = val
}
(*res)[i].FourXXRate = float32((*res)[i].Num4XX) * 100 / float32((*res)[i].NumCalls)
(*res)[i].ErrorRate = float32((*res)[i].NumErrors) * 100 / float32((*res)[i].NumCalls)
(*res)[i].CallRate = float32((*res)[i].NumCalls) / float32(query.Period)
}
servicesResponse := (*res)[1:]
return &servicesResponse, nil
}
func GetServiceMapDependencies(client *SqlClient, query *model.GetServicesParams) (*[]model.ServiceMapDependencyResponseItem, error) {
sqlQuery := fmt.Sprintf(`SELECT SpanId, ParentSpanId, ServiceName FROM %s WHERE "__time" >= '%s' AND "__time" <= '%s' ORDER BY __time DESC LIMIT 100000`, constants.DruidDatasource, query.StartTime, query.EndTime)
// zap.S().Debug(sqlQuery)
response, err := client.Query(sqlQuery, "object")
if err != nil {
zap.S().Error(query, err)
return nil, fmt.Errorf("Something went wrong in druid query")
}
// responseStr := string(response)
// zap.S().Info(responseStr)
res := new([]model.ServiceMapDependencyItem)
err = json.Unmarshal(response, res)
if err != nil {
zap.S().Error(err)
return nil, fmt.Errorf("Error in unmarshalling response from druid")
}
// resCount := len(*res)
// fmt.Println(resCount)
serviceMap := make(map[string]*model.ServiceMapDependencyResponseItem)
spanId2ServiceNameMap := make(map[string]string)
for i, _ := range *res {
spanId2ServiceNameMap[(*res)[i].SpanId] = (*res)[i].ServiceName
}
for i, _ := range *res {
parent2childServiceName := spanId2ServiceNameMap[(*res)[i].ParentSpanId] + "-" + spanId2ServiceNameMap[(*res)[i].SpanId]
if _, ok := serviceMap[parent2childServiceName]; !ok {
serviceMap[parent2childServiceName] = &model.ServiceMapDependencyResponseItem{
Parent: spanId2ServiceNameMap[(*res)[i].ParentSpanId],
Child: spanId2ServiceNameMap[(*res)[i].SpanId],
CallCount: 1,
}
} else {
serviceMap[parent2childServiceName].CallCount++
}
}
retMe := make([]model.ServiceMapDependencyResponseItem, 0, len(serviceMap))
for _, dependency := range serviceMap {
if dependency.Parent == "" {
continue
}
retMe = append(retMe, *dependency)
}
return &retMe, nil
}

View File

@ -1,419 +0,0 @@
package druidQuery
import (
"encoding/json"
"fmt"
"time"
"go.signoz.io/query-service/constants"
"go.signoz.io/query-service/godruid"
"go.signoz.io/query-service/model"
"go.uber.org/zap"
)
func check(e error) {
if e != nil {
panic(e)
}
}
type DurationItem struct {
Value float32 `json:"value"`
QuantileAgg int `json:"quantile_agg"`
}
type SpanSearchAggregatesDuratonReceivedItem struct {
Timestamp string `json:"timestamp"`
Result DurationItem `json:"result"`
}
func buildFilters(queryParams *model.SpanSearchParams) (*godruid.Filter, error) {
var filter *godruid.Filter
if len(queryParams.ServiceName) != 0 {
filter = godruid.FilterSelector("ServiceName", queryParams.ServiceName)
}
if len(queryParams.OperationName) != 0 {
newFilter := godruid.FilterSelector("Name", queryParams.OperationName)
filter = godruid.FilterAnd(filter, newFilter)
}
if len(queryParams.Kind) != 0 {
newFilter := godruid.FilterSelector("Kind", queryParams.Kind)
filter = godruid.FilterAnd(filter, newFilter)
}
// zap.S().Debug("MinDuration: ", queryParams.MinDuration)
var lower string
var upper string
if len(queryParams.MinDuration) != 0 {
lower = queryParams.MinDuration
}
if len(queryParams.MaxDuration) != 0 {
upper = queryParams.MaxDuration
}
if len(lower) != 0 || len(upper) != 0 {
newFilter := godruid.FilterBound("DurationNano", lower, upper, false, false, "numeric")
filter = godruid.FilterAnd(filter, newFilter)
}
for _, item := range queryParams.Tags {
var newFilter *godruid.Filter
if item.Operator == "equals" {
newFilter = godruid.FilterSelector("Tags", fmt.Sprintf("%s:%s", item.Key, item.Value))
} else if item.Operator == "contains" {
valuesFilter := godruid.FilterSearch("TagsValues", fmt.Sprintf("%s", item.Value))
keysFilter := godruid.FilterSelector("TagsKeys", fmt.Sprintf("%s", item.Key))
newFilter = godruid.FilterAnd(valuesFilter, keysFilter)
} else if item.Operator == "isnotnull" {
newFilter = godruid.FilterSelector("TagsKeys", fmt.Sprintf("%s", item.Key))
} else {
return nil, fmt.Errorf("Tag Operator %s not supported", item.Operator)
}
if item.Key == "error" && item.Value == "true" {
statusCodeHttpFilter := godruid.FilterBound("StatusCode", "500", "600", false, true, "numeric")
statusCodeGrpcFilter := godruid.FilterBound("StatusCode", "2", "2", false, false, "numeric")
filterError := godruid.FilterOr(statusCodeHttpFilter, statusCodeGrpcFilter, newFilter)
filter = godruid.FilterAnd(filter, filterError)
continue
}
filter = godruid.FilterAnd(filter, newFilter)
}
// if filter == nil {
// return nil, fmt.Errorf("No search criteria for spans was specified")
// }
return filter, nil
}
func buildFiltersForSpansAggregates(queryParams *model.SpanSearchAggregatesParams) (*godruid.Filter, error) {
var filter *godruid.Filter
if len(queryParams.ServiceName) != 0 {
filter = godruid.FilterSelector("ServiceName", queryParams.ServiceName)
}
if len(queryParams.OperationName) != 0 {
newFilter := godruid.FilterSelector("Name", queryParams.OperationName)
filter = godruid.FilterAnd(filter, newFilter)
}
if len(queryParams.Kind) != 0 {
newFilter := godruid.FilterSelector("Kind", queryParams.Kind)
filter = godruid.FilterAnd(filter, newFilter)
}
// zap.S().Debug("MinDuration: ", queryParams.MinDuration)
var lower string
var upper string
if len(queryParams.MinDuration) != 0 {
lower = queryParams.MinDuration
}
if len(queryParams.MaxDuration) != 0 {
upper = queryParams.MaxDuration
}
if len(lower) != 0 || len(upper) != 0 {
newFilter := godruid.FilterBound("DurationNano", lower, upper, false, false, "numeric")
filter = godruid.FilterAnd(filter, newFilter)
}
for _, item := range queryParams.Tags {
var newFilter *godruid.Filter
if item.Operator == "equals" {
newFilter = godruid.FilterSelector("Tags", fmt.Sprintf("%s:%s", item.Key, item.Value))
} else if item.Operator == "contains" {
valuesFilter := godruid.FilterSearch("TagsValues", fmt.Sprintf("%s", item.Value))
keysFilter := godruid.FilterSelector("TagsKeys", fmt.Sprintf("%s", item.Key))
newFilter = godruid.FilterAnd(valuesFilter, keysFilter)
} else if item.Operator == "isnotnull" {
newFilter = godruid.FilterSelector("TagsKeys", fmt.Sprintf("%s", item.Key))
} else {
return nil, fmt.Errorf("Tag Operator %s not supported", item.Operator)
}
if item.Key == "error" && item.Value == "true" {
statusCodeHttpFilter := godruid.FilterBound("StatusCode", "500", "600", false, true, "numeric")
statusCodeGrpcFilter := godruid.FilterBound("StatusCode", "2", "2", false, false, "numeric")
filterError := godruid.FilterOr(statusCodeHttpFilter, statusCodeGrpcFilter, newFilter)
filter = godruid.FilterAnd(filter, filterError)
continue
}
filter = godruid.FilterAnd(filter, newFilter)
}
// newFilter := godruid.FilterSelector("Kind", "2")
// filter = godruid.FilterAnd(filter, newFilter)
// if filter == nil {
// return nil, fmt.Errorf("No search criteria for spans was specified")
// }
return filter, nil
}
func SearchTraces(client *godruid.Client, traceId string) (*[]model.SearchSpansResult, error) {
filter := godruid.FilterSelector("TraceId", traceId)
query := &godruid.QueryScan{
DataSource: constants.DruidDatasource,
Intervals: []string{"-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z"},
Filter: filter,
Columns: []string{"__time", "SpanId", "TraceId", "ServiceName", "Name", "Kind", "DurationNano", "TagsKeys", "TagsValues", "References"},
Order: "none",
BatchSize: 20480,
}
clientErr := client.Query(query)
// fmt.Println("requst", client.LastRequest)
if clientErr != nil {
// fmt.Println("Error: ", err)
zap.S().Error(zap.Error(clientErr))
return nil, clientErr
}
// fmt.Println("response", client.LastResponse)
// fmt.Printf("query.QueryResult:\n%v", query.QueryResult)
var searchSpansResult []model.SearchSpansResult
searchSpansResult = make([]model.SearchSpansResult, len(query.QueryResult))
searchSpansResult[0].Columns = make([]string, len(query.QueryResult[0].Columns))
copy(searchSpansResult[0].Columns, query.QueryResult[0].Columns)
searchSpansResult[0].Events = make([][]interface{}, len(query.QueryResult[0].Events))
copy(searchSpansResult[0].Events, query.QueryResult[0].Events)
return &searchSpansResult, nil
}
func SearchSpansAggregate(client *godruid.Client, queryParams *model.SpanSearchAggregatesParams) ([]model.SpanSearchAggregatesResponseItem, error) {
filter, err := buildFiltersForSpansAggregates(queryParams)
var needsPostAggregation bool = true
if err != nil {
return nil, err
}
granularity := godruid.GranPeriod{
Type: "period",
Period: queryParams.GranPeriod,
// Origin: queryParams.GranOrigin,
}
var aggregation godruid.Aggregation
var postAggregation godruid.PostAggregation
if queryParams.Dimension == "duration" {
switch queryParams.AggregationOption {
case "p50":
aggregationString := `{ "type": "quantilesDoublesSketch", "fieldName": "QuantileDuration", "name": "quantile_agg", "k": 128}`
aggregation = godruid.AggRawJson(aggregationString)
postAggregationString := `{"type":"quantilesDoublesSketchToQuantile","name":"value","field":{"type":"fieldAccess","fieldName":"quantile_agg"},"fraction":0.5}`
postAggregation = godruid.PostAggRawJson(postAggregationString)
break
case "p95":
aggregationString := `{ "type": "quantilesDoublesSketch", "fieldName": "QuantileDuration", "name": "quantile_agg", "k": 128}`
aggregation = godruid.AggRawJson(aggregationString)
postAggregationString := `{"type":"quantilesDoublesSketchToQuantile","name":"value","field":{"type":"fieldAccess","fieldName":"quantile_agg"},"fraction":0.95}`
postAggregation = godruid.PostAggRawJson(postAggregationString)
break
case "p99":
aggregationString := `{ "type": "quantilesDoublesSketch", "fieldName": "QuantileDuration", "name": "quantile_agg", "k": 128}`
aggregation = godruid.AggRawJson(aggregationString)
postAggregationString := `{"type":"quantilesDoublesSketchToQuantile","name":"value","field":{"type":"fieldAccess","fieldName":"quantile_agg"},"fraction":0.99}`
postAggregation = godruid.PostAggRawJson(postAggregationString)
break
}
} else if queryParams.Dimension == "calls" {
aggregation = godruid.AggCount("value")
needsPostAggregation = false
}
var query *godruid.QueryTimeseries
if needsPostAggregation {
query = &godruid.QueryTimeseries{
DataSource: constants.DruidDatasource,
Intervals: []string{queryParams.Intervals},
Granularity: granularity,
Filter: filter,
Aggregations: []godruid.Aggregation{aggregation},
PostAggregations: []godruid.PostAggregation{postAggregation},
}
} else {
query = &godruid.QueryTimeseries{
DataSource: constants.DruidDatasource,
Intervals: []string{queryParams.Intervals},
Granularity: granularity,
Filter: filter,
Aggregations: []godruid.Aggregation{aggregation},
// PostAggregations: []godruid.PostAggregation{postAggregation},
}
}
clientErr := client.Query(query)
// fmt.Println("requst", client.LastRequest)
if clientErr != nil {
// fmt.Println("Error: ", err)
zap.S().Error(zap.Error(clientErr))
return nil, clientErr
}
// fmt.Println("response", client.LastResponse)
receivedResponse := new([]SpanSearchAggregatesDuratonReceivedItem)
err = json.Unmarshal([]byte(client.LastResponse), receivedResponse)
if err != nil && len(*receivedResponse) == 0 {
zap.S().Error(err)
return nil, fmt.Errorf("Error in unmarshalling response from druid")
}
var response []model.SpanSearchAggregatesResponseItem
for _, elem := range *receivedResponse {
value := elem.Result.Value
timeObj, _ := time.Parse(time.RFC3339Nano, elem.Timestamp)
timestamp := timeObj.UnixNano()
if queryParams.AggregationOption == "rate_per_sec" {
value = elem.Result.Value * 1.0 / float32(queryParams.StepSeconds)
}
response = append(response, model.SpanSearchAggregatesResponseItem{
Timestamp: timestamp,
Value: value,
})
}
return response, nil
// fmt.Printf("query.QueryResult:\n%v", query.QueryResult)
return nil, nil
}
func SearchSpans(client *godruid.Client, queryParams *model.SpanSearchParams) (*[]model.SearchSpansResult, error) {
filter, err := buildFilters(queryParams)
if err != nil {
return nil, err
}
query := &godruid.QueryScan{
DataSource: constants.DruidDatasource,
Intervals: []string{queryParams.Intervals},
Filter: filter,
Columns: []string{"__time", "SpanId", "TraceId", "ServiceName", "Name", "Kind", "DurationNano", "TagsKeys", "TagsValues"},
Limit: queryParams.Limit,
Offset: queryParams.Offset,
Order: "descending",
BatchSize: 20480,
}
clientErr := client.Query(query)
// fmt.Println("requst", client.LastRequest)
if clientErr != nil {
// fmt.Println("Error: ", err)
zap.S().Error(zap.Error(clientErr))
return nil, clientErr
}
// fmt.Println("response", client.LastResponse)
// fmt.Printf("query.QueryResult:\n%v", query.QueryResult)
var searchSpansResult []model.SearchSpansResult
searchSpansResult = make([]model.SearchSpansResult, len(query.QueryResult))
searchSpansResult[0].Columns = make([]string, len(query.QueryResult[0].Columns))
copy(searchSpansResult[0].Columns, query.QueryResult[0].Columns)
searchSpansResult[0].Events = make([][]interface{}, len(query.QueryResult[0].Events))
copy(searchSpansResult[0].Events, query.QueryResult[0].Events)
return &searchSpansResult, nil
}
func GetApplicationPercentiles(client *godruid.Client, queryParams *model.ApplicationPercentileParams) ([]godruid.Timeseries, error) {
// query := &godruid.QueryGroupBy{
// DataSource: constants.DruidDatasource,
// Intervals: []string{"2020-12-11T05:23:00.000Z/2020-12-11T05:24:00.000Z"},
// Granularity: godruid.GranMinute,
// Filter: godruid.FilterSelector("Kind", "2"),
// Dimensions: []godruid.DimSpec{"ServiceName"},
// Aggregations: []godruid.Aggregation{godruid.AggRawJson(`{ "type" : "count", "name" : "count" }`)},
// }
granularity := godruid.GranPeriod{
Type: "period",
Period: queryParams.GranPeriod,
Origin: queryParams.GranOrigin,
}
filterKind := godruid.FilterSelector("Kind", "2")
filterService := godruid.FilterSelector("ServiceName", queryParams.ServiceName)
filter := godruid.FilterAnd(filterKind, filterService)
aggregationString := `{ "type": "quantilesDoublesSketch", "fieldName": "QuantileDuration", "name": "quantile_agg", "k": 128}`
aggregation := godruid.AggRawJson(aggregationString)
postAggregationString := `{"type":"quantilesDoublesSketchToQuantiles","name":"final_quantile","field":{"type":"fieldAccess","fieldName":"quantile_agg"},"fractions":[0.5,0.99]}`
postAggregation := godruid.PostAggRawJson(postAggregationString)
query := &godruid.QueryTimeseries{
DataSource: constants.DruidDatasource,
Intervals: []string{queryParams.Intervals},
Granularity: granularity,
Filter: filter,
Aggregations: []godruid.Aggregation{aggregation},
PostAggregations: []godruid.PostAggregation{postAggregation},
}
err := client.Query(query)
// fmt.Println("requst", client.LastRequest)
if err != nil {
// fmt.Println("Error: ", err)
zap.S().Error(zap.Error(err))
return nil, err
}
// fmt.Println("response", client.LastResponse)
// fmt.Printf("query.QueryResult:\n%v", query.QueryResult)
return query.QueryResult, nil
}

View File

@ -1,79 +1,139 @@
module go.signoz.io/query-service
go 1.14
go 1.17
require (
cloud.google.com/go v0.88.0 // indirect
github.com/ClickHouse/clickhouse-go v1.5.4
github.com/Microsoft/go-winio v0.5.1 // indirect
github.com/OneOfOne/xxhash v1.2.8 // indirect
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da // indirect
github.com/aws/aws-sdk-go v1.27.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/containerd/containerd v1.4.12 // indirect
github.com/dhui/dktest v0.3.4 // indirect
github.com/docker/docker v20.10.12+incompatible // indirect
github.com/frankban/quicktest v1.13.0 // indirect
github.com/ClickHouse/clickhouse-go/v2 v2.0.12
github.com/go-kit/log v0.1.0
github.com/golang-migrate/migrate/v4 v4.14.1
github.com/golang/snappy v0.0.4 // indirect
github.com/google/uuid v1.3.0
github.com/gorilla/handlers v1.5.1
github.com/gorilla/mux v1.8.0
github.com/gosimple/slug v1.10.0
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
github.com/hashicorp/go-cleanhttp v0.5.0 // indirect
github.com/hashicorp/go-immutable-radix v1.0.0 // indirect
github.com/hashicorp/go-msgpack v1.1.5 // indirect
github.com/hashicorp/go-sockaddr v1.0.0 // indirect
github.com/hashicorp/go-uuid v1.0.2 // indirect
github.com/hashicorp/memberlist v0.1.0 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/jmoiron/sqlx v1.3.4
github.com/json-iterator/go v1.1.10
github.com/kr/text v0.2.0 // indirect
github.com/lib/pq v1.10.0 // indirect
github.com/mattn/go-sqlite3 v1.14.8
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
github.com/minio/minio-go v6.0.14+incompatible
github.com/minio/minio-go/v6 v6.0.57
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect
github.com/oklog/oklog v0.3.2
github.com/oklog/run v1.1.0 // indirect
github.com/onsi/gomega v1.14.0 // indirect
github.com/opencontainers/image-spec v1.0.2 // indirect
github.com/opentracing/opentracing-go v1.1.0 // indirect
github.com/pascaldekloe/goe v0.1.0 // indirect
github.com/pierrec/lz4 v2.4.1+incompatible // indirect
github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v0.9.0-pre1.0.20181001174001-0a8115f42e03
github.com/prometheus/common v0.0.0-20180518154759-7600349dcfe1
github.com/prometheus/procfs v0.0.8 // indirect
github.com/prometheus/prometheus v2.5.0+incompatible
github.com/prometheus/tsdb v0.0.0-20181003080831-0ce41118ed20
github.com/rs/cors v1.7.0
github.com/smartystreets/goconvey v1.6.4
github.com/soheilhy/cmux v0.1.4
go.uber.org/zap v1.16.0
gopkg.in/segmentio/analytics-go.v3 v3.1.0
k8s.io/apimachinery v0.0.0-20180621070125-103fd098999d
)
require (
github.com/klauspost/cpuid v1.2.3 // indirect
github.com/minio/md5-simd v1.1.0 // indirect
github.com/minio/sha256-simd v0.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
gopkg.in/ini.v1 v1.42.0 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
)
require (
cloud.google.com/go v0.88.0 // indirect
github.com/Azure/azure-sdk-for-go v5.0.0-beta.0.20161028183111-bd73d950fa44+incompatible // indirect
github.com/Azure/go-autorest v10.8.1+incompatible // indirect
github.com/OneOfOne/xxhash v1.2.8 // indirect
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da // indirect
github.com/aws/aws-sdk-go v1.27.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect
github.com/cespare/xxhash v1.1.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
github.com/felixge/httpsnoop v1.0.1 // indirect
github.com/fsnotify/fsnotify v1.4.9 // indirect
github.com/ghodss/yaml v1.0.0 // indirect
github.com/go-kit/kit v0.4.1-0.20170517165212-6964666de57c // indirect
github.com/go-logfmt/logfmt v0.5.0 // indirect
github.com/go-stack/stack v1.8.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/glog v0.0.0-20210429001901-424d2337a529 // indirect
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/btree v1.0.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/googleapis/gax-go/v2 v2.0.5 // indirect
github.com/googleapis/gnostic v0.2.3-0.20180520015035-48a0ecefe2e4 // indirect
github.com/gophercloud/gophercloud v0.0.0-20170607034829-caf34a65f602 // indirect
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 // indirect
github.com/gosimple/unidecode v1.0.0 // indirect
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect
github.com/hashicorp/consul v1.1.1-0.20180615161029-bed22a81e9fd // indirect
github.com/hashicorp/go-cleanhttp v0.5.0 // indirect
github.com/hashicorp/go-immutable-radix v1.0.0 // indirect
github.com/hashicorp/go-msgpack v1.1.5 // indirect
github.com/hashicorp/go-multierror v1.1.0 // indirect
github.com/hashicorp/go-rootcerts v0.0.0-20160503143440-6bb64b370b90 // indirect
github.com/hashicorp/go-sockaddr v1.0.0 // indirect
github.com/hashicorp/go-uuid v1.0.2 // indirect
github.com/hashicorp/golang-lru v0.5.1 // indirect
github.com/hashicorp/memberlist v0.1.0 // indirect
github.com/hashicorp/serf v0.8.1-0.20161007004122-1d4fa605f6ff // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/jtolds/gls v4.20.0+incompatible // indirect
github.com/kr/text v0.2.0 // indirect
github.com/lib/pq v1.10.0 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
github.com/miekg/dns v1.0.4 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 // indirect
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223 // indirect
github.com/oklog/run v1.1.0 // indirect
github.com/oklog/ulid v0.3.1-0.20170117200651-66bb6560562f // indirect
github.com/opentracing/opentracing-go v1.1.0 // indirect
github.com/pascaldekloe/goe v0.1.0 // indirect
github.com/paulmach/orb v0.4.0 // indirect
github.com/peterbourgon/diskv v2.0.2-0.20180312054125-0646ccaebea1+incompatible // indirect
github.com/pierrec/lz4/v4 v4.1.14 // indirect
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 // indirect
github.com/prometheus/procfs v0.0.8 // indirect
github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da // indirect
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 // indirect
github.com/segmentio/backo-go v1.0.0 // indirect
github.com/smartystreets/goconvey v1.6.4
github.com/soheilhy/cmux v0.1.4
github.com/shopspring/decimal v1.3.1 // indirect
github.com/sirupsen/logrus v1.8.1 // indirect
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d // indirect
github.com/spaolacci/murmur3 v1.1.0 // indirect
github.com/stretchr/testify v1.7.0
github.com/spf13/pflag v1.0.3 // indirect
github.com/stretchr/testify v1.7.1
github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c // indirect
go.uber.org/zap v1.16.0
go.opencensus.io v0.23.0 // indirect
go.opentelemetry.io/otel v1.4.1 // indirect
go.opentelemetry.io/otel/trace v1.4.1 // indirect
go.uber.org/atomic v1.6.0 // indirect
go.uber.org/multierr v1.5.0 // indirect
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect
golang.org/x/net v0.0.0-20211013171255-e13a2654a71e // indirect
golang.org/x/sys v0.0.0-20211013075003-97ac67df715c // indirect
golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914 // indirect
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
golang.org/x/sys v0.0.0-20211110154304-99a53858aa08 // indirect
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 // indirect
golang.org/x/text v0.3.7 // indirect
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e // indirect
google.golang.org/api v0.51.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20211013025323-ce878158c4d4 // indirect
google.golang.org/grpc v1.41.0 // indirect
google.golang.org/grpc/examples v0.0.0-20210803221256-6ba56c814be7 // indirect
google.golang.org/protobuf v1.27.1 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/fsnotify/fsnotify.v1 v1.4.7 // indirect
gopkg.in/segmentio/analytics-go.v3 v3.1.0
gotest.tools/v3 v3.1.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
k8s.io/api v0.0.0-20180628040859-072894a440bd // indirect
k8s.io/client-go v8.0.0+incompatible // indirect
)
replace github.com/prometheus/prometheus => github.com/SigNoz/prometheus v1.9.69
replace github.com/prometheus/prometheus => github.com/SigNoz/prometheus v1.9.70

View File

@ -12,8 +12,6 @@ cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bP
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.63.0/go.mod h1:GmezbQc7T2snqkEXWfZ0sy0VfkB/ivI2DdtJL2DEmlg=
cloud.google.com/go v0.64.0/go.mod h1:xfORb36jGvE+6EexW71nMEtL025s3x6xvuYUKM4JLv4=
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
@ -37,7 +35,6 @@ cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2k
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/spanner v1.9.0/go.mod h1:xvlEn0NZ5v1iJPYsBnUVRDNvccDxsBTEi16pJRKQVws=
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=
@ -46,46 +43,35 @@ cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/Azure/azure-sdk-for-go v5.0.0-beta.0.20161028183111-bd73d950fa44+incompatible h1:+5hx+ZckahrubYyxbjTwnq9w5xpnq1CwSL4N54I8/qc=
github.com/Azure/azure-sdk-for-go v5.0.0-beta.0.20161028183111-bd73d950fa44+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
github.com/Azure/go-autorest v10.8.1+incompatible h1:u0jVQf+a6k6x8A+sT60l6EY9XZu+kHdnZVPAYqpVRo0=
github.com/Azure/go-autorest v10.8.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
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/ClickHouse/clickhouse-go v1.3.12/go.mod h1:EaI/sW7Azgz9UATzd5ZdZHRUhHgv5+JMS9NSr2smCJI=
github.com/ClickHouse/clickhouse-go v1.4.5/go.mod h1:EaI/sW7Azgz9UATzd5ZdZHRUhHgv5+JMS9NSr2smCJI=
github.com/ClickHouse/clickhouse-go v1.5.4 h1:cKjXeYLNWVJIx2J1K6H2CqyRmfwVJVY1OV1coaaFcI0=
github.com/ClickHouse/clickhouse-go v1.5.4/go.mod h1:EaI/sW7Azgz9UATzd5ZdZHRUhHgv5+JMS9NSr2smCJI=
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
github.com/Microsoft/go-winio v0.5.1 h1:aPJp2QD7OOrhO5tQXqQoGSJc+DjDtWTGLOmNyAm6FgY=
github.com/Microsoft/go-winio v0.5.1/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
github.com/ClickHouse/clickhouse-go v1.5.3 h1:Vok8zUb/wlqc9u8oEqQzBMBRDoFd8NxPRqgYEqMnV88=
github.com/ClickHouse/clickhouse-go v1.5.3/go.mod h1:EaI/sW7Azgz9UATzd5ZdZHRUhHgv5+JMS9NSr2smCJI=
github.com/ClickHouse/clickhouse-go/v2 v2.0.12 h1:Nbl/NZwoM6LGJm7smNBgvtdr/rxjlIssSW3eG/Nmb9E=
github.com/ClickHouse/clickhouse-go/v2 v2.0.12/go.mod h1:u4RoNQLLM2W6hNSPYrIESLJqaWSInZVmfM+MlaAhXcg=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8=
github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q=
github.com/SigNoz/prometheus v1.9.69 h1:DJogqPVErWpXG4rFz8euICdS7x/GFmMKRT7f4MJVw1I=
github.com/SigNoz/prometheus v1.9.69/go.mod h1:BHEawFYBYkVr9BjPXsz9Ye6QVVQ+2a99m6r/S8hO/lA=
github.com/SigNoz/prometheus v1.9.70 h1:0214i78cje5MkX0tXYwX2cK4cHXrFw18WcSLhv4YDpk=
github.com/SigNoz/prometheus v1.9.70/go.mod h1:Y4J9tGDmacMC+EcOTp+EIAn2C1sN+9kE+idyVKadiVM=
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/apache/arrow/go/arrow v0.0.0-20200601151325-b2287a20f230/go.mod h1:QNYViu/X0HXDHw7m3KXzWSVXIbfUvJqBFe6Gj8/pYA0=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da h1:8GUt8eRujhVEGZFFEjBj46YV4rDjvGrNxb0KMWYkL2I=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
github.com/aws/aws-sdk-go v1.13.44-0.20180507225419-00862f899353/go.mod h1:ZRmQr0FajVIyZ4ZzBYKG5P3ZqPz9IHG41ZoMu1ADI3k=
github.com/aws/aws-sdk-go v1.17.7/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/aws/aws-sdk-go v1.27.0 h1:0xphMHGMLBrPMfxR2AmVjZKcMEESEgWF8Kru94BNByk=
github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/beorn7/perks v0.0.0-20160229213445-3ac7bf7a47d1/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
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/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k=
github.com/bkaradzic/go-lz4 v1.0.0 h1:RXc4wYsyz985CkXXeX04y4VnZFGG8Rd43pRaHsOXAKk=
github.com/bkaradzic/go-lz4 v1.0.0/go.mod h1:0YdlkowM3VswSROI7qDxhRvJ3sLhlFrRRwjwegp5jy4=
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY=
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
github.com/cenkalti/backoff/v4 v4.0.2/go.mod h1:eEew/i+1Q6OrCDZh3WiXYv3+nJwBASZ8Bog/87DQnVg=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash v0.0.0-20161118035902-4a94f899c20b/go.mod h1:fX/lfQBkSCDXZSUgv6jVIu/EVA3/JNseAX5asI4c4T4=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
@ -95,52 +81,23 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR
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/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58 h1:F1EaeKL/ta07PY/k9Os/UFtwERei2/XzGemhpGnBKNg=
github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58/go.mod h1:EOBUe0h4xcZ5GoxqC5SDxFQ8gwyZPKQoEzownBlhI80=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
github.com/cockroachdb/cmux v0.0.0-20170110192607-30d10be49292/go.mod h1:qRiX68mZX1lGBkTWyp3CLcenw9I94W2dLeRvMzcn9N4=
github.com/cockroachdb/cockroach v0.0.0-20170608034007-84bc9597164f/go.mod h1:xeT/CQ0qZHangbYbWShlCGAx31aV4AjGswDUjhKS6HQ=
github.com/cockroachdb/cockroach-go v0.0.0-20190925194419-606b3d062051/go.mod h1:XGLbWH/ujMcbPbhZq52Nv6UrCghb1yGn//133kEsvDk=
github.com/containerd/containerd v1.4.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
github.com/containerd/containerd v1.4.1/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
github.com/containerd/containerd v1.4.3/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
github.com/containerd/containerd v1.4.12 h1:V+SHzYmhng/iju6M5nFrpTTusrhidoxKTwdwLw+u4c4=
github.com/containerd/containerd v1.4.12/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw=
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/cznic/mathutil v0.0.0-20180504122225-ca4c9f2c1369/go.mod h1:e6NPNENfs9mPDVNRekM7lKScauxd5kXTr1Mfyig6TDM=
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/denisenkom/go-mssqldb v0.0.0-20200620013148-b91950f658ec/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
github.com/dgrijalva/jwt-go v3.0.1-0.20161101193935-9ed569b5d1ac+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-bits v0.0.0-20160601073636-2ad8d707cc05/go.mod h1:/9UYwwvZuEgp+mQ4960SHWCU1FS+FgdFX+m5ExFByNs=
github.com/dhui/dktest v0.3.3/go.mod h1:EML9sP4sqJELHn4jV7B0TY8oF6077nk83/tz7M56jcQ=
github.com/dhui/dktest v0.3.4 h1:VbUEcaSP+U2/yUr9d2JhSThXYEnDlGabRSHe2rIE46E=
github.com/dhui/dktest v0.3.4/go.mod h1:4m4n6lmXlmVfESth7mzdcv8nBI5mOb5UROPqjM02csU=
github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug=
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v17.12.0-ce-rc1.0.20200618181300-9dc6525e6118+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker v17.12.0-ce-rc1.0.20210128214336-420b1d36250f+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker v20.10.12+incompatible h1:CEeNmFM0QZIsJCZKMkZx0ZcahTiewkrgiwfYD+dfl1U=
github.com/docker/docker v20.10.12+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
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=
@ -152,18 +109,13 @@ github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ=
github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/frankban/quicktest v1.13.0 h1:yNZif1OkDfNoDfb9zZa9aXIpejNR4F23Wely0c+Qdqk=
github.com/frankban/quicktest v1.13.0/go.mod h1:qLE0fzW0VuyUAJgPU19zByoIr0HtCHN/r/VLSOOIySU=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fsouza/fake-gcs-server v1.17.0/go.mod h1:D1rTE4YCyHFNa99oyJJ5HyclvN/0uQR+pM/VdlL83bw=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
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-ini/ini v1.21.1 h1:+QXUYsI7Tfxc64oD6R5BxU/Aq+UwGkyjH4W/hMNG7bg=
github.com/go-ini/ini v1.21.1/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
github.com/go-kit/kit v0.4.1-0.20170517165212-6964666de57c h1:lGtNy7NU/+ytYPPneoErOaNrYkF5DOVCYViUK/7t7XA=
github.com/go-kit/kit v0.4.1-0.20170517165212-6964666de57c/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
@ -172,22 +124,17 @@ github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vb
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.5.0 h1:TrB8swr/68K7m9CcGut2g3UOihhbcbiMAYiuTXdEih4=
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM=
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-stack/stack v1.5.4/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/gobuffalo/here v0.6.0/go.mod h1:wAG085dHOYqUpf+Ap+WOdrPTp5IYcDAs/x7PLa8Y5fM=
github.com/gocql/gocql v0.0.0-20190301043612-f6df8288f9b4/go.mod h1:4Fw1eo5iaEhDUs8XyuhSVCVy52Jq3L+/3GJgYkwc+/0=
github.com/gogo/protobuf v0.0.0-20171123125729-971cbfd2e72b/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang-migrate/migrate/v4 v4.14.1 h1:qmRd/rNGjM1r3Ve5gHd5ZplytrD02UcItYNxJ3iUHHE=
github.com/golang-migrate/migrate/v4 v4.14.1/go.mod h1:l7Ks0Au6fYHuUIxUhQ0rcVX1uLlJg54C/VvW7tvxSz0=
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/glog v0.0.0-20210429001901-424d2337a529 h1:2voWjNECnrZRbfwXxHB1/j8wa6xdKn85B5NzgVL/pTU=
github.com/golang/glog v0.0.0-20210429001901-424d2337a529/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
@ -204,7 +151,6 @@ github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/golang/protobuf v1.0.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
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=
@ -224,8 +170,6 @@ github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/snappy v0.0.0-20160529050041-d9eb7a3d35ec/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
@ -233,7 +177,6 @@ github.com/google/btree v0.0.0-20180124185431-e89373fe6b4a/go.mod h1:lNA+9X1NB3Z
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
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=
@ -245,12 +188,9 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.3/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/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY=
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
@ -274,7 +214,6 @@ github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLe
github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210715191844-86eeefc3e471/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
@ -287,15 +226,12 @@ github.com/gophercloud/gophercloud v0.0.0-20170607034829-caf34a65f602 h1:Acc1d6m
github.com/gophercloud/gophercloud v0.0.0-20170607034829-caf34a65f602/go.mod h1:3WdhXV3rUYy9p6AUW8d94kr+HS62Y4VL9mBnFxsD8q4=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
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/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4=
github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q=
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/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gosimple/slug v1.10.0 h1:3XbiQua1IpCdrvuntWvGBxVm+K99wCSxJjlxkP49GGQ=
github.com/gosimple/slug v1.10.0/go.mod h1:MICb3w495l9KNdZm+Xn5b6T2Hn831f9DMxiJ1r+bAjw=
github.com/gosimple/unidecode v1.0.0 h1:kPdvM+qy0tnk4/BrnkrbdJ82xe88xn7c9hcaipDz4dQ=
@ -305,7 +241,6 @@ github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJr
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4=
github.com/hashicorp/consul v1.1.1-0.20180615161029-bed22a81e9fd h1:u6o+bd6FHxDKoCSa8PJ5vrHhAYSKgJtAHQtLO1EYgos=
github.com/hashicorp/consul v1.1.1-0.20180615161029-bed22a81e9fd/go.mod h1:mFrjN1mfidgJfYP1xrJCF+AfRhr6Eaqhb2+sfyn/OOI=
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
@ -334,34 +269,9 @@ github.com/hashicorp/memberlist v0.1.0 h1:qSsCiC0WYD39lbSitKNt40e30uorm2Ss/d4JGU
github.com/hashicorp/memberlist v0.1.0/go.mod h1:ncdBp14cuox2iFOq3kDiquKU6fqsTBc3W6JvZwjxxsE=
github.com/hashicorp/serf v0.8.1-0.20161007004122-1d4fa605f6ff h1:epPiU3hEuHbpThFTQSGbdBBJemXM7aNQIU1thmpucTU=
github.com/hashicorp/serf v0.8.1-0.20161007004122-1d4fa605f6ff/go.mod h1:h/Ru6tmZazX7WO/GDmwdpS975F019L4t5ng5IgwbNrE=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/influxdata/influxdb v1.2.3-0.20170331210902-15e594fc09f1/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY=
github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA=
github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE=
github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s=
github.com/jackc/pgconn v1.3.2/go.mod h1:LvCquS3HbBKwgl7KbX9KyqEIumJAbm1UMcTvGaIf3bM=
github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8=
github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE=
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78=
github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA=
github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg=
github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
github.com/jackc/pgproto3/v2 v2.0.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg=
github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc=
github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw=
github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y=
github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM=
github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc=
github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
@ -380,41 +290,24 @@ github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/X
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/julienschmidt/httprouter v1.1.1-0.20150905172533-109e267447e9/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k=
github.com/k0kubun/pp v2.3.0+incompatible/go.mod h1:GWse8YhT0p8pT4ir3ZgBbfZild3tgzSScAn6HmfYukg=
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8=
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
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/klauspost/cpuid v1.2.3 h1:CCtW0xUnWGVINKvE/WWOYKdsPV6mawAtvQuSl8guwQs=
github.com/klauspost/cpuid v1.2.3/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
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.2/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/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/ktrysmt/go-bitbucket v0.6.4/go.mod h1:9u0v3hsd2rqCHRIpbir1oP7F58uo5dq19sBYvuMoyQ4=
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/lib/pq v1.10.0 h1:Zx5DJFEYQXio93kgXnQ09fXNiUKsqv4OUEu2UtGcB1E=
github.com/lib/pq v1.10.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/markbates/pkger v0.15.1/go.mod h1:0JoVlrol20BSywW79rN3kdFFsE5xYM+rSCQDXbLhiuI=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/mattn/go-sqlite3 v1.14.8 h1:gDp86IdQsN/xWjIEmr9MF6o9mpksUgh0fu+9ByFxzIU=
github.com/mattn/go-sqlite3 v1.14.8/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
@ -425,8 +318,6 @@ github.com/miekg/dns v1.0.4 h1:Ec3LTJwwzqT1++63P12fhtdEbQhtPE7TBdD6rlhqrMM=
github.com/miekg/dns v1.0.4/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/minio/md5-simd v1.1.0 h1:QPfiOqlZH+Cj9teu0t9b1nTBfPbyTl16Of5MeuShdK4=
github.com/minio/md5-simd v1.1.0/go.mod h1:XpBqgZULrMYD3R+M28PcmP0CkI7PEMzB3U77ZrKZ0Gw=
github.com/minio/minio-go v6.0.14+incompatible h1:fnV+GD28LeqdN6vT2XdGKW8Qe/IfjJDswNVuni6km9o=
github.com/minio/minio-go v6.0.14+incompatible/go.mod h1:7guKYtitv8dktvNUGrhzmNlA5wrAABTQXCoesZdFQO8=
github.com/minio/minio-go/v6 v6.0.57 h1:ixPkbKkyD7IhnluRgQpGSpHdpvNVaW6OD5R9IAO/9Tw=
github.com/minio/minio-go/v6 v6.0.57/go.mod h1:5+R/nM9Pwrh0vqF+HbYYDQ84wdUFPyXHkrdT4AIkifM=
github.com/minio/sha256-simd v0.1.1 h1:5QHSlgo3nt5yKOJrC7W8w7X+NFl8cMPZm96iu8kKUJU=
@ -436,24 +327,14 @@ github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU=
github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8=
github.com/mitchellh/mapstructure v0.0.0-20180220230111-00c29f56e238/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 h1:dcztxKSvZ4Id8iPpHERQBbIJfabdt4wUm5qy3wOL2Zc=
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6/go.mod h1:E2VnQOmVuvZB6UYnnDB0qG5Nq/1tD9acaOpo6xmt0Kw=
github.com/mkevac/debugcharts v0.0.0-20191222103121-ae1c48aa8615/go.mod h1:Ad7oeElCZqA1Ufj0U9/liOF4BtVepxRcTvr2ey7zTvM=
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 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
github.com/mutecomm/go-sqlcipher/v4 v4.4.0/go.mod h1:PyN04SaWalavxRGH9E8ZftG6Ju7rsPrGmQRjrEaVpiY=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223 h1:F9x/1yl3T2AeKLr2AMdilSD8+f9bvMnNN8VS5iDtovc=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/nakagami/firebirdsql v0.0.0-20190310045651-3c02a58cfed8/go.mod h1:86wM1zFnC6/uDBfZGNwB65O+pR2OFi5q/YQaEUid1qA=
github.com/neo4j/neo4j-go-driver v1.8.1-0.20200803113522-b626aa943eba/go.mod h1:ncO5VaFWh0Nrt+4KT4mOZboaczBZcLuHrG+/sUeP8gI=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/oklog/oklog v0.2.3-0.20170918173356-f857583a70c3/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
github.com/oklog/oklog v0.3.2 h1:wVfs8F+in6nTBMkA7CbRw+zZMIB7nNM825cM1wuzoTk=
github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
@ -461,34 +342,22 @@ github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA=
github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU=
github.com/oklog/ulid v0.3.1-0.20170117200651-66bb6560562f h1:tt7Qj+4Pic1KiUqT7XNMnbAE3TLJAGH+5LMuX4roYbE=
github.com/oklog/ulid v0.3.1-0.20170117200651-66bb6560562f/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc=
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.14.0 h1:ep6kpPVwmr/nTbklSx2nrLNSIO62DoYAhnPNIMhK8gI=
github.com/onsi/gomega v1.14.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM=
github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opentracing-contrib/go-stdlib v0.0.0-20170113013457-1de4cc2120e7/go.mod h1:PLldrQSroqzH70Xl+1DQcGnefIbqsKR7UDaiux3zV+w=
github.com/opentracing/opentracing-go v1.0.1/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU=
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY=
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/paulmach/orb v0.4.0 h1:ilp1MQjRapLJ1+qcays1nZpe0mvkCY+b8JU/qBKRZ1A=
github.com/paulmach/orb v0.4.0/go.mod h1:FkcWtplUAIVqAuhAOV2d3rpbnQyliDOjOcLW9dUrfdU=
github.com/paulmach/protoscan v0.2.1-0.20210522164731-4e53c6875432/go.mod h1:2sV+uZ/oQh66m4XJVZm5iqUZ62BN88Ex1E+TTS0nLzI=
github.com/peterbourgon/diskv v2.0.2-0.20180312054125-0646ccaebea1+incompatible h1:FhnA4iH8T/yYW+AolPONZjGE897wxj3MAzfEbrZkSYw=
github.com/peterbourgon/diskv v2.0.2-0.20180312054125-0646ccaebea1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o=
github.com/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM8aXeqhl0I=
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pierrec/lz4 v2.4.1+incompatible h1:mFe7ttWaflA46Mhqh+jUfjp2qTbPYxLB2/OyBppH9dg=
github.com/pierrec/lz4 v2.4.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA=
github.com/pierrec/lz4/v4 v4.1.14 h1:+fL8AQEZtz/ijeNnpduH0bROTu0O3NZAlPjQxGn8LwE=
github.com/pierrec/lz4/v4 v4.1.14/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
github.com/pkg/errors v0.8.1-0.20161029093637-248dadf4e906/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
@ -506,31 +375,25 @@ github.com/prometheus/procfs v0.0.8 h1:+fpWZdT24pJBiqJdAwYBjPSk+5YmQzYNPYzQsdzLk
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
github.com/prometheus/tsdb v0.0.0-20181003080831-0ce41118ed20 h1:Jh/eKJuru9z9u3rUGdQ8gYc3aZmCGkjXT3gmy0Ex8W8=
github.com/prometheus/tsdb v0.0.0-20181003080831-0ce41118ed20/go.mod h1:lFf/o1J2a31WmWQbxYXfY1azJK5Xp5D8hwKMnVMBTGU=
github.com/remyoudompheng/bigfft v0.0.0-20190728182440-6a916e37a237/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik=
github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
github.com/samuel/go-zookeeper v0.0.0-20161028232340-1d7be4effb13/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da h1:p3Vo3i64TCLY7gIfzeQaUJ+kppEO5WQG3cL8iE8tGHU=
github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/segmentio/backo-go v1.0.0 h1:kbOAtGJY2DqOR0jfRkYEorx/b18RgtepGtY3+Cpe6qA=
github.com/segmentio/backo-go v1.0.0/go.mod h1:kJ9mm9YmoWSkk+oQ+5Cj8DEoRCX2JT6As4kEtIIOp1M=
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
github.com/shirou/gopsutil v2.19.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc=
github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
github.com/shurcooL/vfsgen v0.0.0-20180711163814-62bca832be04/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw=
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.5.0/go.mod h1:+F7Ogzej0PZc/94MaYx/nvG9jOFMD2osvC3s+Squfpo=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
@ -538,8 +401,6 @@ github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/snowflakedb/glog v0.0.0-20180824191149-f5055e6f21ce/go.mod h1:EB/w24pR5VKI60ecFnKqXzxX3dOorz1rnVicQTQrGM0=
github.com/snowflakedb/gosnowflake v1.3.5/go.mod h1:13Ky+lxzIm3VqNDZJdyvu9MCGy+WgRdYFdXp96UcLZU=
github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
@ -549,20 +410,14 @@ github.com/spf13/pflag v1.0.0/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
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/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
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.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/tidwall/pretty v0.0.0-20180105212114-65a9db5fad51/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/xanzy/go-gitlab v0.15.0/go.mod h1:8zdQa/ri1dfn8eS3Ir1SyfvOKlw7WBJ8DVThkpGiXrs=
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c h1:3lbZUMbMiGUW/LMkfsEABsc5zNT9+b1CvsJx47JzJ8g=
github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c/go.mod h1:UrdRz5enIKZ63MEE3IF9l2/ebyx59GyGgPi+tICQdmM=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
@ -570,9 +425,6 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
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.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b/go.mod h1:T3BPAOm2cqquPa0MKWeNkmOM5RQsRhkrwMWonFMN7fE=
go.mongodb.org/mongo-driver v1.1.0/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
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=
@ -581,31 +433,25 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M=
go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
go.opentelemetry.io/otel v1.4.1 h1:QbINgGDDcoQUoMJa2mMaWno49lja9sHwp6aoa2n3a4g=
go.opentelemetry.io/otel v1.4.1/go.mod h1:StM6F/0fSwpd8dKWDCdRr7uRvEPYdW0hBSlbdTiUde4=
go.opentelemetry.io/otel/trace v1.4.1 h1:O+16qcdTrT7zxv2J6GejTPFinSwA++cYerC5iSiF8EQ=
go.opentelemetry.io/otel/trace v1.4.1/go.mod h1:iYEVbroFCNut9QkwEczV9vMRPHNKSSwYZjulEtsmhFc=
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
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.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A=
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4=
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.16.0 h1:uFRZXykJGK9lLY4HtgSw44DnIcAM+kRBP7x5m+NpAOM=
go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@ -645,14 +491,10 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/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-20181108082009-03003ca0c849/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-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190225153610-fe579d43d832/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=
@ -662,7 +504,6 @@ golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR
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=
@ -673,15 +514,11 @@ golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/
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-20200520004742-59133d7f0dd7/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-20200813134508-3edf25e44fcc/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-20201029221708-28c70e62bb1d/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
@ -689,13 +526,10 @@ golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211013171255-e13a2654a71e h1:Xj+JO91noE97IN6F/7WZxzC5QE6yENAQPrwIYhW3bsA=
golang.org/x/net v0.0.0-20211013171255-e13a2654a71e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/oauth2 v0.0.0-20180227000427-d7d64896b5ff/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/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=
@ -721,14 +555,9 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180224232135-f6cff0780e54/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-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-20190403152447-81d4e9dc473e/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=
@ -736,14 +565,11 @@ golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7w
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-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191220220014-0732a990476f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -758,16 +584,12 @@ golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7w
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-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201029080932-201ba4db2418/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -780,8 +602,8 @@ golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211013075003-97ac67df715c h1:taxlMj0D/1sOAuv/CbSD+MMDof2vbyPTqz5FNYKpXt8=
golang.org/x/sys v0.0.0-20211013075003-97ac67df715c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211110154304-99a53858aa08 h1:WecRHqgE09JBkh/584XIE6PMz5KKE/vER4izNUi30AQ=
golang.org/x/sys v0.0.0-20211110154304-99a53858aa08/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@ -801,7 +623,6 @@ golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxb
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e h1:EHBhcS0mlXEAVwNyO2dLfjToGsyY4j24pTs2ScHnX7s=
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/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=
@ -810,15 +631,12 @@ golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190424220101-1e8e1cfdf96b/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/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-20190624222133-a101b041ded4/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-20190823170909-c4a336ef6a2f/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=
@ -848,16 +666,11 @@ golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roY
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-20200806022845-90696ccdc692/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200814230902-9882f1d1823d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200817023811-d00afeaade8f/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200818005847-188abfa75333/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
@ -867,8 +680,6 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
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=
@ -901,9 +712,7 @@ google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtuk
google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw=
google.golang.org/api v0.51.0 h1:SQaA2Cx57B+iPw2MBgyjEkoeMkRK2IenSGoia0U3lCk=
google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU=
google.golang.org/appengine v1.0.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.3.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=
@ -942,16 +751,12 @@ google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7Fc
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-20200806141610-86f49bd18e98/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200815001618-f69a88009b70/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-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200911024640-645f7a48b24f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201030142918-24207fddd1c3/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210207032614-bba0dbe2a9ea/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
@ -980,7 +785,6 @@ google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3Iji
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.31.1/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.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
@ -1017,34 +821,23 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
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/fsnotify/fsnotify.v1 v1.3.0/go.mod h1:Fyux9zXlo4rWoMSIzpn9fDAYjalPqJ/K1qJ27s+7ltE=
gopkg.in/fsnotify/fsnotify.v1 v1.4.7 h1:XNNYLJHt73EyYiCZi6+xjupS9CpvmiDgjPTAjrBlQbo=
gopkg.in/fsnotify/fsnotify.v1 v1.4.7/go.mod h1:Fyux9zXlo4rWoMSIzpn9fDAYjalPqJ/K1qJ27s+7ltE=
gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/ini.v1 v1.42.0 h1:7N3gPTt50s8GuLortA00n8AqRTk75qOP98+mTPpgzRk=
gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/segmentio/analytics-go.v3 v3.1.0 h1:UzxH1uaGZRpMKDhJyBz0pexz6yUoBU3x8bJsRk/HV6U=
gopkg.in/segmentio/analytics-go.v3 v3.1.0/go.mod h1:4QqqlTlSSpVlWA9/9nDcPw+FkM2yv1NQoYjUbL9/JAw=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.3/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.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/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 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
gotest.tools/v3 v3.1.0 h1:rVV8Tcg/8jHUkPUorwjaMTtemIMVXfIPKiOqnhEhakk=
gotest.tools/v3 v3.1.0/go.mod h1:fHy7eyTmJFO5bQbUsEGQ1v4m2J3Jz9eWL54TP2/ZuYQ=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
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=
@ -1061,18 +854,6 @@ k8s.io/client-go v8.0.0+incompatible h1:tTI4hRmb1DRMl4fG6Vclfdi6nTM82oIrTT7Hfitm
k8s.io/client-go v8.0.0+incompatible/go.mod h1:7vJpHMYJwNQCWgzmNV+VYUl1zCObLyodBc8nIyt8L5s=
k8s.io/kube-openapi v0.0.0-20180629012420-d83b052f768a h1:tHgpQvrWaYfrnC8G4N0Oszw5HHCsZxKilDi2R7HuCSM=
k8s.io/kube-openapi v0.0.0-20180629012420-d83b052f768a/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc=
modernc.org/b v1.0.0/go.mod h1:uZWcZfRj1BpYzfN9JTerzlNUnnPsV9O2ZA8JsRcubNg=
modernc.org/db v1.0.0/go.mod h1:kYD/cO29L/29RM0hXYl4i3+Q5VojL31kTUVpVJDw0s8=
modernc.org/file v1.0.0/go.mod h1:uqEokAEn1u6e+J45e54dsEA/pw4o7zLrA2GwyntZzjw=
modernc.org/fileutil v1.0.0/go.mod h1:JHsWpkrk/CnVV1H/eGlFf85BEpfkrp56ro8nojIq9Q8=
modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk=
modernc.org/internal v1.0.0/go.mod h1:VUD/+JAkhCpvkUitlEOnhpVxCgsBI90oTzSCRcqQVSM=
modernc.org/lldb v1.0.0/go.mod h1:jcRvJGWfCGodDZz8BPwiKMJxGJngQ/5DrRapkQnLob8=
modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k=
modernc.org/ql v1.0.0/go.mod h1:xGVyrLIatPcO2C1JvI/Co8c0sr6y91HKFNy4pt9JXEY=
modernc.org/sortutil v1.1.0/go.mod h1:ZyL98OQHJgH9IEfN71VsamvJgrtRX9Dj2gX+vH86L1k=
modernc.org/strutil v1.1.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs=
modernc.org/zappy v1.0.0/go.mod h1:hHe+oGahLVII/aTTyWK/b53VDHMAGCBYYeZ9sn83HC4=
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=

View File

@ -1,24 +0,0 @@
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
*.a
*.so
# Folders
_obj
_test
# Architecture specific extensions/prefixes
*.[568vq]
[568vq].out
*.cgo1.go
*.cgo2.c
_cgo_defun.c
_cgo_gotypes.go
_cgo_export.*
_testmain.go
*.exe
*.test
*.prof

View File

@ -1,22 +0,0 @@
The MIT License (MIT)
Copyright (c) 2014 shunfei
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.

View File

@ -1,9 +0,0 @@
godruid
=======
An open source Golang client for Druid
**Node:** This project is not yet beta released. It should certainly contains bugs, and the apis could change in any time. So please be really careful if you choose to use it in production. Currently the [groupBy](http://druid.io/docs/latest/GroupByQuery.html) and [topN](http://druid.io/docs/latest/TopNQuery.html) queries are used in our production.
Any bug fixes, issues, contributions, questions are welcome.

View File

@ -1,85 +0,0 @@
package godruid
import (
"encoding/json"
)
type Aggregation struct {
Type string `json:"type"`
Name string `json:"name,omitempty"`
FieldName string `json:"fieldName,omitempty"`
FieldNames []string `json:"fieldNames,omitempty"`
FnAggregate string `json:"fnAggregate,omitempty"`
FnCombine string `json:"fnCombine,omitempty"`
FnReset string `json:"fnReset,omitempty"`
ByRow bool `json:"byRow,omitempty"`
}
func AggRawJson(rawJson string) Aggregation {
agg := &Aggregation{}
json.Unmarshal([]byte(rawJson), agg)
return *agg
}
func AggCount(name string) Aggregation {
return Aggregation{
Type: "count",
Name: name,
}
}
func AggLongSum(name, fieldName string) Aggregation {
return Aggregation{
Type: "longSum",
Name: name,
FieldName: fieldName,
}
}
func AggDoubleSum(name, fieldName string) Aggregation {
return Aggregation{
Type: "doubleSum",
Name: name,
FieldName: fieldName,
}
}
func AggMin(name, fieldName string) Aggregation {
return Aggregation{
Type: "min",
Name: name,
FieldName: fieldName,
}
}
func AggMax(name, fieldName string) Aggregation {
return Aggregation{
Type: "max",
Name: name,
FieldName: fieldName,
}
}
func AggJavaScript(name, fnAggregate, fnCombine, fnReset string, fieldNames []string) Aggregation {
return Aggregation{
Type: "javascript",
Name: name,
FieldNames: fieldNames,
FnAggregate: fnAggregate,
FnCombine: fnCombine,
FnReset: fnReset,
}
}
func AggCardinality(name string, fieldNames []string, byRow ...bool) Aggregation {
isByRow := false
if len(byRow) != 0 {
isByRow = byRow[0]
}
return Aggregation{
Type: "cardinality",
Name: name,
FieldNames: fieldNames,
ByRow: isByRow,
}
}

View File

@ -1,97 +0,0 @@
package godruid
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"time"
"go.uber.org/zap"
)
const (
DefaultEndPoint = "/druid/v2"
)
type Client struct {
Url string
EndPoint string
Timeout time.Duration
Debug bool
LastRequest string
LastResponse string
}
func (c *Client) Query(query Query) (err error) {
query.setup()
var reqJson []byte
if c.Debug {
reqJson, err = json.MarshalIndent(query, "", " ")
} else {
reqJson, err = json.Marshal(query)
}
if err != nil {
return
}
// log request made to druid
zap.S().Info(string(reqJson))
result, err := c.QueryRaw(reqJson)
if err != nil {
return
}
return query.onResponse(result)
}
func (c *Client) QueryRaw(req []byte) (result []byte, err error) {
if c.EndPoint == "" {
c.EndPoint = DefaultEndPoint
}
endPoint := c.EndPoint
if c.Debug {
endPoint += "?pretty"
c.LastRequest = string(req)
}
if err != nil {
return
}
// By default, use 60 second timeout unless specified otherwise
// by the caller
clientTimeout := 60 * time.Second
if c.Timeout != 0 {
clientTimeout = c.Timeout
}
httpClient := &http.Client{
Timeout: clientTimeout,
}
resp, err := httpClient.Post(c.Url+endPoint, "application/json", bytes.NewBuffer(req))
if err != nil {
return
}
defer func() {
resp.Body.Close()
}()
result, err = ioutil.ReadAll(resp.Body)
if err != nil {
return
}
if c.Debug {
c.LastResponse = string(result)
}
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("%s: %s", resp.Status, string(result))
}
return
}

View File

@ -1,64 +0,0 @@
package godruid
import (
"fmt"
. "github.com/smartystreets/goconvey/convey"
"testing"
)
func TestGroupby(t *testing.T) {
Convey("TestGroupby", t, func() {
query := &QueryGroupBy{
DataSource: "campaign",
Intervals: []string{"2014-09-01T00:00/2020-01-01T00"},
Granularity: GranAll,
Filter: FilterAnd(FilterJavaScript("hour", "function(x) { return(x >= 1) }"), nil),
LimitSpec: LimitDefault(5),
Dimensions: []DimSpec{"campaign_id"},
Aggregations: []Aggregation{AggRawJson(`{ "type" : "count", "name" : "count" }`), AggLongSum("impressions", "impressions")},
PostAggregations: []PostAggregation{PostAggArithmetic("imp/count", "/", []PostAggregation{
PostAggFieldAccessor("impressions"),
PostAggRawJson(`{ "type" : "fieldAccess", "fieldName" : "count" }`)})},
}
client := Client{
Url: "http://192.168.10.60:8009",
Debug: true,
}
err := client.Query(query)
fmt.Println("requst", client.LastRequest)
So(err, ShouldEqual, nil)
fmt.Println("response", client.LastResponse)
fmt.Printf("query.QueryResult:\n%v", query.QueryResult)
})
}
func TestSearch(t *testing.T) {
// return
Convey("TestSearch", t, func() {
query := &QuerySearch{
DataSource: "campaign",
Intervals: []string{"2014-09-01T00:00/2020-01-01T00"},
Granularity: GranAll,
SearchDimensions: []string{"campaign_id", "hour"},
Query: SearchQueryInsensitiveContains(1313),
Sort: SearchSortLexicographic,
}
client := Client{
Url: "http://192.168.10.60:8009",
Debug: true,
}
err := client.Query(query)
So(err, ShouldEqual, nil)
fmt.Println("requst", client.LastRequest)
fmt.Println("response", client.LastResponse)
fmt.Printf("query.QueryResult:\n%v", query.QueryResult)
})
}

View File

@ -1,72 +0,0 @@
package godruid
type DimSpec interface{}
type Dimension struct {
Type string `json:"type"`
Dimension string `json:"dimension"`
OutputName string `json:"outputName"`
DimExtractionFn *DimExtractionFn `json:"dimExtractionFn,omitempty"`
}
type DimExtractionFn struct {
Type string `json:"type"`
Expr string `json:"expr,omitempty"`
Query *SearchQuery `json:"query,omitempty"`
TimeFormat string `json:"timeFormat,omitempty"`
ResultFormat string `json:"resultFormat,omitempty"`
Function string `json:"function,omitempty"`
}
func DimDefault(dimension, outputName string) DimSpec {
return &Dimension{
Type: "default",
Dimension: dimension,
OutputName: outputName,
}
}
func DimExtraction(dimension, outputName string, fn *DimExtractionFn) DimSpec {
return &Dimension{
Type: "extraction",
Dimension: dimension,
OutputName: outputName,
DimExtractionFn: fn,
}
}
func DimExFnRegex(expr string) *DimExtractionFn {
return &DimExtractionFn{
Type: "regex",
Expr: expr,
}
}
func DimExFnPartial(expr string) *DimExtractionFn {
return &DimExtractionFn{
Type: "partial",
Expr: expr,
}
}
func DimExFnSearchQuerySpec(query *SearchQuery) *DimExtractionFn {
return &DimExtractionFn{
Type: "searchQuery",
Query: query,
}
}
func DimExFnTime(timeFormat, resultFormat string) *DimExtractionFn {
return &DimExtractionFn{
Type: "time",
TimeFormat: timeFormat,
ResultFormat: resultFormat,
}
}
func DimExFnJavascript(function string) *DimExtractionFn {
return &DimExtractionFn{
Type: "javascript",
Function: function,
}
}

View File

@ -1,110 +0,0 @@
package godruid
type FilterQueryType struct {
Type string `json:"type"`
Value interface{} `json:"value"`
}
type Filter struct {
Type string `json:"type"`
Dimension string `json:"dimension,omitempty"`
Value interface{} `json:"value,omitempty"`
Pattern string `json:"pattern,omitempty"`
Function string `json:"function,omitempty"`
Field *Filter `json:"field,omitempty"`
Fields []*Filter `json:"fields,omitempty"`
Lower string `json:"lower,omitempty"`
LowerStrict bool `json:"lowerStrict,omitempty"`
Upper string `json:"upper,omitempty"`
UpperStrict bool `json:"upperStrict,omitempty"`
Ordering string `json:"ordering,omitempty"`
Query FilterQueryType `json:"query,omitempty"`
}
func FilterSelector(dimension string, value interface{}) *Filter {
return &Filter{
Type: "selector",
Dimension: dimension,
Value: value,
}
}
func FilterBound(dimension string, lower string, upper string, lowerStrict bool, upperStrict bool, ordering string) *Filter {
return &Filter{
Type: "bound",
Dimension: dimension,
Lower: lower,
LowerStrict: lowerStrict,
Upper: upper,
UpperStrict: upperStrict,
Ordering: ordering,
}
}
func FilterRegex(dimension, pattern string) *Filter {
return &Filter{
Type: "regex",
Dimension: dimension,
Pattern: pattern,
}
}
func FilterSearch(dimension string, value interface{}) *Filter {
return &Filter{
Type: "search",
Dimension: dimension,
Query: FilterQueryType{
Type: "insensitive_contains",
Value: value,
},
}
}
func FilterJavaScript(dimension, function string) *Filter {
return &Filter{
Type: "javascript",
Dimension: dimension,
Function: function,
}
}
func FilterAnd(filters ...*Filter) *Filter {
return joinFilters(filters, "and")
}
func FilterOr(filters ...*Filter) *Filter {
return joinFilters(filters, "or")
}
func FilterNot(filter *Filter) *Filter {
return &Filter{
Type: "not",
Field: filter,
}
}
func joinFilters(filters []*Filter, connector string) *Filter {
// Remove null filters.
p := 0
for _, f := range filters {
if f != nil {
filters[p] = f
p++
}
}
filters = filters[0:p]
fLen := len(filters)
if fLen == 0 {
return nil
}
if fLen == 1 {
return filters[0]
}
return &Filter{
Type: connector,
Fields: filters,
}
}

View File

@ -1,30 +0,0 @@
package godruid
type Granlarity interface{}
type SimpleGran string
const (
GranAll SimpleGran = "all"
GranNone SimpleGran = "none"
GranMinute SimpleGran = "minute"
GranFifteenMin SimpleGran = "fifteen_minute"
GranThirtyMin SimpleGran = "thirty_minute"
GranHour SimpleGran = "hour"
GranDay SimpleGran = "day"
)
type GranDuration struct {
Type string `json:"type"`
Duration string `json:"duration"`
Origin string `json:"origin,omitempty"`
}
type GranPeriod struct {
Type string `json:"type"`
Period string `json:"period"`
TimeZone string `json:"timeZone,omitempty"`
Origin string `json:"origin,omitempty"`
}

View File

@ -1,73 +0,0 @@
package godruid
type Having struct {
Type string `json:"type"`
Aggregation string `json:"aggregation,omitempty"`
Value interface{} `json:"value,omitempty"`
HavingSpec *Having `json:"havingSpec,omitempty"`
HavingSpecs []*Having `json:"havingSpecs,omitempty"`
}
func HavingEqualTo(agg string, value interface{}) *Having {
return &Having{
Type: "equalTo",
Aggregation: agg,
Value: value,
}
}
func HavingGreaterThan(agg string, value interface{}) *Having {
return &Having{
Type: "greaterThan",
Aggregation: agg,
Value: value,
}
}
func HavingLessThan(agg string, value interface{}) *Having {
return &Having{
Type: "lessThan",
Aggregation: agg,
Value: value,
}
}
func HavingAnd(havings ...*Having) *Having {
return joinHavings(havings, "and")
}
func HavingOr(havings ...*Having) *Having {
return joinHavings(havings, "or")
}
func HavingNot(having *Having) *Having {
return &Having{
Type: "not",
HavingSpec: having,
}
}
func joinHavings(havings []*Having, connector string) *Having {
// Remove null havings.
p := 0
for _, h := range havings {
if h != nil {
havings[p] = h
p++
}
}
havings = havings[0:p]
fLen := len(havings)
if fLen == 0 {
return nil
}
if fLen == 1 {
return havings[0]
}
return &Having{
Type: connector,
HavingSpecs: havings,
}
}

View File

@ -1,110 +0,0 @@
package godruid
import (
"encoding/json"
)
type PostAggregation struct {
Type string `json:"type"`
Name string `json:"name,omitempty"`
Value interface{} `json:"value,omitempty"`
Fn string `json:"fn,omitempty"`
Field PostAggregationField `json:"field,omitempty"`
Fields []PostAggregation `json:"fields,omitempty"`
FieldName string `json:"fieldName,omitempty"`
FieldNames []string `json:"fieldNames,omitempty"`
Function string `json:"function,omitempty"`
Fraction float32 `json:"fraction,omitempty"`
Fractions []float32 `json:"fractions,omitempty"`
}
type PostAggregationField struct {
Type string `json:"type,omitempty"`
FieldName string `json:"fieldName,omitempty"`
}
func NewPostAggregationField(fieldName string) PostAggregationField {
return PostAggregationField{
Type: "fieldAccess",
FieldName: fieldName,
}
}
// The agg reference.
type AggRefer struct {
Name string
Refer string // The refer of Name, empty means Name has no refer.
}
// Return the aggregations or post aggregations which this post aggregation used.
// It could be helpful while automatically filling the aggregations or post aggregations base on this.
func (pa PostAggregation) GetReferAggs(parentName ...string) (refers []AggRefer) {
switch pa.Type {
case "arithmetic":
if len(parentName) != 0 {
refers = append(refers, AggRefer{parentName[0], pa.Name})
} else {
refers = append(refers, AggRefer{pa.Name, ""})
}
for _, spa := range pa.Fields {
refers = append(refers, spa.GetReferAggs(pa.Name)...)
}
case "fieldAccess":
refers = append(refers, AggRefer{parentName[0], pa.FieldName})
case "constant":
// no need refers.
case "javascript":
for _, f := range pa.FieldNames {
refers = append(refers, AggRefer{pa.Name, f})
}
case "hyperUniqueCardinality":
refers = append(refers, AggRefer{parentName[0], pa.FieldName})
}
return
}
func PostAggRawJson(rawJson string) PostAggregation {
pa := &PostAggregation{}
json.Unmarshal([]byte(rawJson), pa)
return *pa
}
func PostAggArithmetic(name, fn string, fields []PostAggregation) PostAggregation {
return PostAggregation{
Type: "arithmetic",
Name: name,
Fn: fn,
Fields: fields,
}
}
func PostAggFieldAccessor(fieldName string) PostAggregation {
return PostAggregation{
Type: "fieldAccess",
FieldName: fieldName,
}
}
func PostAggConstant(name string, value interface{}) PostAggregation {
return PostAggregation{
Type: "constant",
Name: name,
Value: value,
}
}
func PostAggJavaScript(name, function string, fieldNames []string) PostAggregation {
return PostAggregation{
Type: "javascript",
Name: name,
FieldNames: fieldNames,
Function: function,
}
}
func PostAggFieldHyperUnique(fieldName string) PostAggregation {
return PostAggregation{
Type: "hyperUniqueCardinality",
FieldName: fieldName,
}
}

View File

@ -1,324 +0,0 @@
package godruid
import (
"encoding/json"
)
// Check http://druid.io/docs/0.6.154/Querying.html#query-operators for detail description.
// The Query interface stands for any kinds of druid query.
type Query interface {
setup()
onResponse(content []byte) error
}
// ---------------------------------
// GroupBy Query
// ---------------------------------
type QueryGroupBy struct {
QueryType string `json:"queryType"`
DataSource string `json:"dataSource"`
Dimensions []DimSpec `json:"dimensions"`
Granularity Granlarity `json:"granularity"`
LimitSpec *Limit `json:"limitSpec,omitempty"`
Having *Having `json:"having,omitempty"`
Filter *Filter `json:"filter,omitempty"`
Aggregations []Aggregation `json:"aggregations"`
PostAggregations []PostAggregation `json:"postAggregations,omitempty"`
Intervals []string `json:"intervals"`
Context map[string]interface{} `json:"context,omitempty"`
QueryResult []GroupbyItem `json:"-"`
}
type GroupbyItem struct {
Version string `json:"version"`
Timestamp string `json:"timestamp"`
Event map[string]interface{} `json:"event"`
}
func (q *QueryGroupBy) setup() { q.QueryType = "groupBy" }
func (q *QueryGroupBy) onResponse(content []byte) error {
res := new([]GroupbyItem)
err := json.Unmarshal(content, res)
if err != nil {
return err
}
q.QueryResult = *res
return nil
}
// ---------------------------------
// Scan Query
// ---------------------------------
type QueryScan struct {
QueryType string `json:"queryType"`
DataSource string `json:"dataSource"`
Filter *Filter `json:"filter,omitempty"`
Intervals []string `json:"intervals"`
Columns []string `json:"columns,omitempty"`
Limit int64 `json:"limit,omitempty"`
Offset int64 `json:"offset,omitempty"`
BatchSize int64 `json:"batchSize,omitempty"`
Order string `json:"order,omitempty"`
ResultFormat string `json:"resultFormat"`
Context map[string]interface{} `json:"context,omitempty"`
QueryResult []ScanResult `json:"-"`
}
type ScanResult struct {
SegmentId string `json:"segmentId"`
Columns []string `json:"columns"`
Events [][]interface{} `json:"events"`
}
func (q *QueryScan) setup() {
q.QueryType = "scan"
q.ResultFormat = "compactedList"
// q.BatchSize = 20480
// q.Limit = 10
}
func (q *QueryScan) onResponse(content []byte) error {
// fmt.Println(string(content))
res := new([]ScanResult)
err := json.Unmarshal(content, res)
if err != nil {
return err
}
q.QueryResult = *res
return nil
}
// ---------------------------------
// Search Query
// ---------------------------------
type QuerySearch struct {
QueryType string `json:"queryType"`
DataSource string `json:"dataSource"`
Granularity Granlarity `json:"granularity"`
Filter *Filter `json:"filter,omitempty"`
Intervals []string `json:"intervals"`
SearchDimensions []string `json:"searchDimensions,omitempty"`
Query *SearchQuery `json:"query"`
Sort *SearchSort `json:"sort"`
Context map[string]interface{} `json:"context,omitempty"`
QueryResult []SearchItem `json:"-"`
}
type SearchItem struct {
Timestamp string `json:"timestamp"`
Result []DimValue `json:"result"`
}
type DimValue struct {
Dimension string `json:"dimension"`
Value string `json:"value"`
}
func (q *QuerySearch) setup() { q.QueryType = "search" }
func (q *QuerySearch) onResponse(content []byte) error {
res := new([]SearchItem)
err := json.Unmarshal(content, res)
if err != nil {
return err
}
q.QueryResult = *res
return nil
}
// ---------------------------------
// SegmentMetadata Query
// ---------------------------------
type QuerySegmentMetadata struct {
QueryType string `json:"queryType"`
DataSource string `json:"dataSource"`
Intervals []string `json:"intervals"`
ToInclude *ToInclude `json:"toInclude,omitempty"`
Merge interface{} `json:"merge,omitempty"`
Context map[string]interface{} `json:"context,omitempty"`
QueryResult []SegmentMetaData `json:"-"`
}
type SegmentMetaData struct {
Id string `json:"id"`
Intervals []string `json:"intervals"`
Columns map[string]ColumnItem `json:"columns"`
}
type ColumnItem struct {
Type string `json:"type"`
Size int `json:"size"`
Cardinality interface{} `json:"cardinality"`
}
func (q *QuerySegmentMetadata) setup() { q.QueryType = "segmentMetadata" }
func (q *QuerySegmentMetadata) onResponse(content []byte) error {
res := new([]SegmentMetaData)
err := json.Unmarshal(content, res)
if err != nil {
return err
}
q.QueryResult = *res
return nil
}
// ---------------------------------
// TimeBoundary Query
// ---------------------------------
type QueryTimeBoundary struct {
QueryType string `json:"queryType"`
DataSource string `json:"dataSource"`
Bound string `json:"bound,omitempty"`
Context map[string]interface{} `json:"context,omitempty"`
QueryResult []TimeBoundaryItem `json:"-"`
}
type TimeBoundaryItem struct {
Timestamp string `json:"timestamp"`
Result TimeBoundary `json:"result"`
}
type TimeBoundary struct {
MinTime string `json:"minTime"`
MaxTime string `json:"maxTime"`
}
func (q *QueryTimeBoundary) setup() { q.QueryType = "timeBoundary" }
func (q *QueryTimeBoundary) onResponse(content []byte) error {
res := new([]TimeBoundaryItem)
err := json.Unmarshal(content, res)
if err != nil {
return err
}
q.QueryResult = *res
return nil
}
// ---------------------------------
// Timeseries Query
// ---------------------------------
type QueryTimeseries struct {
QueryType string `json:"queryType"`
DataSource string `json:"dataSource"`
Granularity Granlarity `json:"granularity"`
Filter *Filter `json:"filter,omitempty"`
Aggregations []Aggregation `json:"aggregations"`
PostAggregations []PostAggregation `json:"postAggregations,omitempty"`
Intervals []string `json:"intervals"`
Context map[string]interface{} `json:"context,omitempty"`
QueryResult []Timeseries `json:"-"`
}
type Timeseries struct {
Timestamp string `json:"timestamp"`
Result map[string]interface{} `json:"result"`
}
func (q *QueryTimeseries) setup() { q.QueryType = "timeseries" }
func (q *QueryTimeseries) onResponse(content []byte) error {
res := new([]Timeseries)
err := json.Unmarshal(content, res)
if err != nil {
return err
}
q.QueryResult = *res
return nil
}
// ---------------------------------
// TopN Query
// ---------------------------------
type QueryTopN struct {
QueryType string `json:"queryType"`
DataSource string `json:"dataSource"`
Granularity Granlarity `json:"granularity"`
Dimension DimSpec `json:"dimension"`
Threshold int `json:"threshold"`
Metric *TopNMetric `json:"metric"`
Filter *Filter `json:"filter,omitempty"`
Aggregations []Aggregation `json:"aggregations"`
PostAggregations []PostAggregation `json:"postAggregations,omitempty"`
Intervals []string `json:"intervals"`
Context map[string]interface{} `json:"context,omitempty"`
QueryResult []TopNItem `json:"-"`
}
type TopNItem struct {
Timestamp string `json:"timestamp"`
Result []map[string]interface{} `json:"result"`
}
func (q *QueryTopN) setup() { q.QueryType = "topN" }
func (q *QueryTopN) onResponse(content []byte) error {
res := new([]TopNItem)
err := json.Unmarshal(content, res)
if err != nil {
return err
}
q.QueryResult = *res
return nil
}
// ---------------------------------
// Select Query
// ---------------------------------
type QuerySelect struct {
QueryType string `json:"queryType"`
DataSource string `json:"dataSource"`
Intervals []string `json:"intervals"`
Filter *Filter `json:"filter,omitempty"`
Dimensions []DimSpec `json:"dimensions"`
Metrics []string `json:"metrics"`
Granularity Granlarity `json:"granularity"`
PagingSpec map[string]interface{} `json:"pagingSpec,omitempty"`
Context map[string]interface{} `json:"context,omitempty"`
QueryResult SelectBlob `json:"-"`
}
// Select json blob from druid comes back as following:
// http://druid.io/docs/latest/querying/select-query.html
// the interesting results are in events blob which we
// call as 'SelectEvent'.
type SelectBlob struct {
Timestamp string `json:"timestamp"`
Result SelectResult `json:"result"`
}
type SelectResult struct {
PagingIdentifiers map[string]interface{} `json:"pagingIdentifiers"`
Events []SelectEvent `json:"events"`
}
type SelectEvent struct {
SegmentId string `json:"segmentId"`
Offset int64 `json:"offset"`
Event map[string]interface{} `json:"event"`
}
func (q *QuerySelect) setup() { q.QueryType = "select" }
func (q *QuerySelect) onResponse(content []byte) error {
res := new([]SelectBlob)
err := json.Unmarshal(content, res)
if err != nil {
return err
}
if len(*res) > 0 {
q.QueryResult = (*res)[0]
}
return nil
}

View File

@ -1,132 +0,0 @@
package godruid
// Defines some small spec like structs here.
// ---------------------------------
// LimitSpec
// ---------------------------------
type Limit struct {
Type string `json:"type"`
Limit int `json:"limit"`
Columns []Column `json:"columns,omitempty"`
}
const (
DirectionASC = "ASCENDING"
DirectionDESC = "DESCENDING"
)
type Column struct {
AsNumber bool `json:"asNumber"`
Dimension string `json:"dimension"`
Direction string `json:"direction"`
}
func LimitDefault(limit int, columns ...[]Column) *Limit {
var realColums []Column
if len(columns) > 0 {
realColums = columns[0]
}
return &Limit{
Type: "default",
Limit: limit,
Columns: realColums,
}
}
// ---------------------------------
// SearchQuerySpec
// ---------------------------------
type SearchQuery struct {
Type string `json:"type"`
Value interface{} `json:"value,omitempty"`
Values []interface{} `json:"values,omitempty"`
}
func SearchQueryInsensitiveContains(value interface{}) *SearchQuery {
return &SearchQuery{
Type: "insensitive_contains",
Value: value,
}
}
func SearchQueryFragmentSearch(values []interface{}) *SearchQuery {
return &SearchQuery{
Type: "fragment",
Values: values,
}
}
// ---------------------------------
// ToInclude
// ---------------------------------
type ToInclude struct {
Type string `json:"type"`
Columns []string `json:"columns,omitempty"`
}
var (
ToIncludeAll = &ToInclude{Type: "All"}
ToIncludeNone = &ToInclude{Type: "None"}
)
func ToIncludeList(columns []string) *ToInclude {
return &ToInclude{
Type: "list",
Columns: columns,
}
}
// ---------------------------------
// TopNMetricSpec
// ---------------------------------
type TopNMetric struct {
Type string `json:"type"`
Metric interface{} `json:"metric,omitempty"`
PreviousStop string `json:"previousStop"`
}
func TopNMetricNumeric(metric string) *TopNMetric {
return &TopNMetric{
Type: "numeric",
Metric: metric,
}
}
func TopNMetricLexicographic(previousStop string) *TopNMetric {
return &TopNMetric{
Type: "lexicographic",
PreviousStop: previousStop,
}
}
func TopNMetricAlphaNumeric(previousStop string) *TopNMetric {
return &TopNMetric{
Type: "alphaNumeric",
PreviousStop: previousStop,
}
}
func TopNMetricInverted(metric *TopNMetric) *TopNMetric {
return &TopNMetric{
Type: "inverted",
Metric: metric,
}
}
// ---------------------------------
// SearchSortSpec
// ---------------------------------
type SearchSort struct {
Type string `json:"type"`
}
var (
SearchSortLexicographic = &SearchSort{Type: "lexicographic"}
SearchSortStrlen = &SearchSort{Type: "strlen"}
)

View File

@ -5,9 +5,6 @@ import (
"os/signal"
"syscall"
_ "github.com/golang-migrate/migrate/v4/database/postgres"
_ "github.com/golang-migrate/migrate/v4/source/github"
"go.signoz.io/query-service/app"
"go.signoz.io/query-service/constants"
"go.signoz.io/query-service/version"

View File

@ -1,7 +1,6 @@
package model
import (
"fmt"
"time"
)
@ -25,12 +24,43 @@ type QueryRangeParams struct {
Stats string
}
type Query struct {
Datasource string `json:"datasource"`
Format string `json:"format"`
Expr string `json:"expr"`
}
type QueryRangeParamsV2 struct {
Start time.Time
End time.Time
Step time.Duration
StartStr string `json:"start"`
EndStr string `json:"end"`
StepStr string `json:"step"`
Queries []Query `json:"queries"`
}
func (params QueryRangeParamsV2) sanitizeAndValidate() (*QueryRangeParamsV2, error) {
return nil, nil
}
type metricTags map[string]string
type MetricAutocompleteTagParams struct {
MetricName string
MetricTags metricTags
Match string
TagKey string
}
type GetTopEndpointsParams struct {
StartTime string
EndTime string
ServiceName string
StartTime string `json:"start"`
EndTime string `json:"end"`
ServiceName string `json:"service"`
Start *time.Time
End *time.Time
Tags []TagQuery `json:"tags"`
}
type GetUsageParams struct {
@ -44,125 +74,78 @@ type GetUsageParams struct {
}
type GetServicesParams struct {
StartTime string
EndTime string
StartTime string `json:"start"`
EndTime string `json:"end"`
Period int
Start *time.Time
End *time.Time
Tags []TagQuery `json:"tags"`
}
type GetServiceOverviewParams struct {
StartTime string
EndTime string
StartTime string `json:"start"`
EndTime string `json:"end"`
Period string
Start *time.Time
End *time.Time
ServiceName string
Period string
StepSeconds int
}
type ApplicationPercentileParams struct {
ServiceName string
GranOrigin string
GranPeriod string
Intervals string
}
func (query *ApplicationPercentileParams) SetGranPeriod(step int) {
minutes := step / 60
query.GranPeriod = fmt.Sprintf("PT%dM", minutes)
Tags []TagQuery `json:"tags"`
ServiceName string `json:"service"`
StepSeconds int `json:"step"`
}
type TagQuery struct {
Key string
Value string
Operator string
}
type TagQueryV2 struct {
Key string
Values []string
Operator string
}
type SpanSearchAggregatesParams struct {
ServiceName string
OperationName string
Kind string
MinDuration string
MaxDuration string
Tags []TagQuery
Start *time.Time
End *time.Time
GranOrigin string
GranPeriod string
Intervals string
StepSeconds int
Dimension string
AggregationOption string
}
type SpanSearchParams struct {
ServiceName string
OperationName string
Kind string
Intervals string
Start *time.Time
End *time.Time
MinDuration string
MaxDuration string
Limit int64
Order string
Offset int64
BatchSize int64
Tags []TagQuery
}
type GetFilteredSpansParams struct {
ServiceName []string `json:"serviceName"`
Operation []string `json:"operation"`
Kind string `json:"kind"`
Status []string `json:"status"`
HttpRoute []string `json:"httpRoute"`
HttpCode []string `json:"httpCode"`
HttpUrl []string `json:"httpUrl"`
HttpHost []string `json:"httpHost"`
HttpMethod []string `json:"httpMethod"`
Component []string `json:"component"`
StartStr string `json:"start"`
EndStr string `json:"end"`
MinDuration string `json:"minDuration"`
MaxDuration string `json:"maxDuration"`
Limit int64 `json:"limit"`
Order string `json:"order"`
Offset int64 `json:"offset"`
Tags []TagQueryV2 `json:"tags"`
Exclude []string `json:"exclude"`
ServiceName []string `json:"serviceName"`
Operation []string `json:"operation"`
Kind string `json:"kind"`
Status []string `json:"status"`
HttpRoute []string `json:"httpRoute"`
HttpCode []string `json:"httpCode"`
HttpUrl []string `json:"httpUrl"`
HttpHost []string `json:"httpHost"`
HttpMethod []string `json:"httpMethod"`
Component []string `json:"component"`
StartStr string `json:"start"`
EndStr string `json:"end"`
MinDuration string `json:"minDuration"`
MaxDuration string `json:"maxDuration"`
Limit int64 `json:"limit"`
OrderParam string `json:"orderParam"`
Order string `json:"order"`
Offset int64 `json:"offset"`
Tags []TagQuery `json:"tags"`
Exclude []string `json:"exclude"`
Start *time.Time
End *time.Time
}
type GetFilteredSpanAggregatesParams struct {
ServiceName []string `json:"serviceName"`
Operation []string `json:"operation"`
Kind string `json:"kind"`
Status []string `json:"status"`
HttpRoute []string `json:"httpRoute"`
HttpCode []string `json:"httpCode"`
HttpUrl []string `json:"httpUrl"`
HttpHost []string `json:"httpHost"`
HttpMethod []string `json:"httpMethod"`
Component []string `json:"component"`
MinDuration string `json:"minDuration"`
MaxDuration string `json:"maxDuration"`
Tags []TagQueryV2 `json:"tags"`
StartStr string `json:"start"`
EndStr string `json:"end"`
StepSeconds int `json:"step"`
Dimension string `json:"dimension"`
AggregationOption string `json:"aggregationOption"`
GroupBy string `json:"groupBy"`
Function string `json:"function"`
Exclude []string `json:"exclude"`
ServiceName []string `json:"serviceName"`
Operation []string `json:"operation"`
Kind string `json:"kind"`
Status []string `json:"status"`
HttpRoute []string `json:"httpRoute"`
HttpCode []string `json:"httpCode"`
HttpUrl []string `json:"httpUrl"`
HttpHost []string `json:"httpHost"`
HttpMethod []string `json:"httpMethod"`
Component []string `json:"component"`
MinDuration string `json:"minDuration"`
MaxDuration string `json:"maxDuration"`
Tags []TagQuery `json:"tags"`
StartStr string `json:"start"`
EndStr string `json:"end"`
StepSeconds int `json:"step"`
Dimension string `json:"dimension"`
AggregationOption string `json:"aggregationOption"`
GroupBy string `json:"groupBy"`
Function string `json:"function"`
Exclude []string `json:"exclude"`
Start *time.Time
End *time.Time
}
@ -208,10 +191,10 @@ type TagFilterParams struct {
}
type TTLParams struct {
Type string // It can be one of {traces, metrics}.
ColdStorageVolume string // Name of the cold storage volume.
ToColdStorageDuration float64 // Seconds after which data will be moved to cold storage.
DelDuration float64 // Seconds after which data will be deleted.
Type string // It can be one of {traces, metrics}.
ColdStorageVolume string // Name of the cold storage volume.
ToColdStorageDuration int64 // Seconds after which data will be moved to cold storage.
DelDuration int64 // Seconds after which data will be deleted.
}
type GetTTLParams struct {

View File

@ -1,15 +1,14 @@
package model
import (
"database/sql"
"encoding/json"
"fmt"
"strconv"
"time"
"github.com/prometheus/prometheus/pkg/labels"
"github.com/prometheus/prometheus/promql"
"github.com/prometheus/prometheus/util/stats"
"k8s.io/apimachinery/pkg/labels"
)
type ApiError struct {
@ -30,6 +29,11 @@ const (
ErrorNotImplemented ErrorType = "not_implemented"
)
type QueryDataV2 struct {
ResultType promql.ValueType `json:"resultType"`
Result promql.Value `json:"result"`
}
type QueryData struct {
ResultType promql.ValueType `json:"resultType"`
Result promql.Value `json:"result"`
@ -68,39 +72,31 @@ type AlertingRuleResponse struct {
}
type ServiceItem struct {
ServiceName string `json:"serviceName" db:"serviceName"`
Percentile99 float32 `json:"p99" db:"p99"`
AvgDuration float32 `json:"avgDuration" db:"avgDuration"`
NumCalls int `json:"numCalls" db:"numCalls"`
CallRate float32 `json:"callRate" db:"callRate"`
NumErrors int `json:"numErrors" db:"numErrors"`
ErrorRate float32 `json:"errorRate" db:"errorRate"`
Num4XX int `json:"num4XX" db:"num4xx"`
FourXXRate float32 `json:"fourXXRate" db:"fourXXRate"`
ServiceName string `json:"serviceName" ch:"serviceName"`
Percentile99 float64 `json:"p99" ch:"p99"`
AvgDuration float64 `json:"avgDuration" ch:"avgDuration"`
NumCalls uint64 `json:"numCalls" ch:"numCalls"`
CallRate float64 `json:"callRate" ch:"callRate"`
NumErrors uint64 `json:"numErrors" ch:"numErrors"`
ErrorRate float64 `json:"errorRate" ch:"errorRate"`
Num4XX uint64 `json:"num4XX" ch:"num4xx"`
FourXXRate float64 `json:"fourXXRate" ch:"fourXXRate"`
}
type ServiceListErrorItem struct {
ServiceName string `json:"serviceName"`
NumErrors int `json:"numErrors"`
Num4xx int `json:"num4xx"`
}
type ServiceErrorItem struct {
Time string `json:"time,omitempty" db:"time,omitempty"`
Timestamp int64 `json:"timestamp" db:"timestamp"`
NumErrors int `json:"numErrors" db:"numErrors"`
Time time.Time `json:"time" ch:"time"`
Timestamp int64 `json:"timestamp" ch:"timestamp"`
NumErrors uint64 `json:"numErrors" ch:"numErrors"`
}
type ServiceOverviewItem struct {
Time string `json:"time,omitempty" db:"time,omitempty"`
Timestamp int64 `json:"timestamp" db:"timestamp"`
Percentile50 float32 `json:"p50" db:"p50"`
Percentile95 float32 `json:"p95" db:"p95"`
Percentile99 float32 `json:"p99" db:"p99"`
NumCalls int `json:"numCalls" db:"numCalls"`
CallRate float32 `json:"callRate" db:"callRate"`
NumErrors int `json:"numErrors" db:"numErrors"`
ErrorRate float32 `json:"errorRate" db:"errorRate"`
Time time.Time `json:"time" ch:"time"`
Timestamp int64 `json:"timestamp" ch:"timestamp"`
Percentile50 float64 `json:"p50" ch:"p50"`
Percentile95 float64 `json:"p95" ch:"p95"`
Percentile99 float64 `json:"p99" ch:"p99"`
NumCalls uint64 `json:"numCalls" ch:"numCalls"`
CallRate float64 `json:"callRate" ch:"callRate"`
NumErrors uint64 `json:"numErrors" ch:"numErrors"`
ErrorRate float64 `json:"errorRate" ch:"errorRate"`
}
type SearchSpansResult struct {
@ -109,60 +105,50 @@ type SearchSpansResult struct {
}
type GetFilterSpansResponseItem struct {
Timestamp string `db:"timestamp" json:"timestamp"`
SpanID string `db:"spanID" json:"spanID"`
TraceID string `db:"traceID" json:"traceID"`
ServiceName string `db:"serviceName" json:"serviceName"`
Operation string `db:"name" json:"operation"`
DurationNano int64 `db:"durationNano" json:"durationNano"`
HttpCode string `db:"httpCode"`
HttpMethod string `db:"httpMethod"`
GRPCode string `db:"gRPCCode"`
GRPMethod string `db:"gRPCMethod"`
StatusCode string `json:"statusCode"`
Method string `json:"method"`
Timestamp time.Time `ch:"timestamp" json:"timestamp"`
SpanID string `ch:"spanID" json:"spanID"`
TraceID string `ch:"traceID" json:"traceID"`
ServiceName string `ch:"serviceName" json:"serviceName"`
Operation string `ch:"name" json:"operation"`
DurationNano uint64 `ch:"durationNano" json:"durationNano"`
HttpCode string `ch:"httpCode"`
HttpMethod string `ch:"httpMethod"`
GRPCode string `ch:"gRPCCode"`
GRPMethod string `ch:"gRPCMethod"`
StatusCode string `json:"statusCode"`
Method string `json:"method"`
}
type GetFilterSpansResponse struct {
Spans []GetFilterSpansResponseItem `json:"spans"`
TotalSpans int `json:"totalSpans"`
TotalSpans uint64 `json:"totalSpans"`
}
type TraceResult struct {
Data []interface{} `json:"data" db:"data"`
Total int `json:"total" db:"total"`
Limit int `json:"limit" db:"limit"`
Offset int `json:"offset" db:"offset"`
type SearchSpanDBReponseItem struct {
Timestamp time.Time `ch:"timestamp"`
TraceID string `ch:"traceID"`
Model string `ch:"model"`
}
type TraceResultItem struct {
TraceID string
Spans []TraceResultSpan
}
type TraceResultSpan struct {
Timestamp string `db:"timestamp"`
SpanID string `db:"spanID"`
TraceID string `db:"traceID"`
ServiceName string `db:"serviceName"`
Name string `db:"name"`
Kind int32 `db:"kind"`
DurationNano int64 `db:"durationNano"`
TagsKeys []string `db:"tagsKeys"`
TagsValues []string `db:"tagsValues"`
type Event struct {
Name string `json:"name,omitempty"`
TimeUnixNano uint64 `json:"timeUnixNano,omitempty"`
AttributeMap map[string]interface{} `json:"attributeMap,omitempty"`
IsError bool `json:"isError,omitempty"`
}
type SearchSpanReponseItem struct {
Timestamp string `db:"timestamp"`
SpanID string `db:"spanID"`
TraceID string `db:"traceID"`
ServiceName string `db:"serviceName"`
Name string `db:"name"`
Kind int32 `db:"kind"`
References string `db:"references,omitempty"`
DurationNano int64 `db:"durationNano"`
TagsKeys []string `db:"tagsKeys"`
TagsValues []string `db:"tagsValues"`
Events []string `db:"events"`
HasError int32 `db:"hasError"`
TimeUnixNano uint64 `json:"timestamp"`
SpanID string `json:"spanID"`
TraceID string `json:"traceID"`
ServiceName string `json:"serviceName"`
Name string `json:"name"`
Kind int32 `json:"kind"`
References []OtelSpanRef `json:"references,omitempty"`
DurationNano int64 `json:"durationNano"`
TagMap map[string]string `json:"tagMap"`
Events []string `json:"event"`
HasError bool `json:"hasError"`
}
type OtelSpanRef struct {
@ -180,82 +166,61 @@ func (ref *OtelSpanRef) toString() string {
func (item *SearchSpanReponseItem) GetValues() []interface{} {
timeObj, _ := time.Parse(time.RFC3339Nano, item.Timestamp)
references := []OtelSpanRef{}
json.Unmarshal([]byte(item.References), &references)
jsonbody, _ := json.Marshal(item.References)
json.Unmarshal(jsonbody, &references)
referencesStringArray := []string{}
for _, item := range references {
referencesStringArray = append(referencesStringArray, item.toString())
}
returnArray := []interface{}{int64(timeObj.UnixNano() / 1000000), item.SpanID, item.TraceID, item.ServiceName, item.Name, strconv.Itoa(int(item.Kind)), strconv.FormatInt(item.DurationNano, 10), item.TagsKeys, item.TagsValues, referencesStringArray, item.Events, item.HasError}
if item.Events == nil {
item.Events = []string{}
}
keys := make([]string, 0, len(item.TagMap))
values := make([]string, 0, len(item.TagMap))
for k, v := range item.TagMap {
keys = append(keys, k)
values = append(values, v)
}
returnArray := []interface{}{item.TimeUnixNano, item.SpanID, item.TraceID, item.ServiceName, item.Name, strconv.Itoa(int(item.Kind)), strconv.FormatInt(item.DurationNano, 10), keys, values, referencesStringArray, item.Events, item.HasError}
return returnArray
}
type ServiceExternalItem struct {
Time string `json:"time,omitempty" db:"time,omitempty"`
Timestamp int64 `json:"timestamp,omitempty" db:"timestamp,omitempty"`
ExternalHttpUrl string `json:"externalHttpUrl,omitempty" db:"externalHttpUrl,omitempty"`
AvgDuration float32 `json:"avgDuration,omitempty" db:"avgDuration,omitempty"`
NumCalls int `json:"numCalls,omitempty" db:"numCalls,omitempty"`
CallRate float32 `json:"callRate,omitempty" db:"callRate,omitempty"`
NumErrors int `json:"numErrors" db:"numErrors"`
ErrorRate float32 `json:"errorRate" db:"errorRate"`
}
type ServiceDBOverviewItem struct {
Time string `json:"time,omitempty" db:"time,omitempty"`
Timestamp int64 `json:"timestamp,omitempty" db:"timestamp,omitempty"`
DBSystem string `json:"dbSystem,omitempty" db:"dbSystem,omitempty"`
AvgDuration float32 `json:"avgDuration,omitempty" db:"avgDuration,omitempty"`
NumCalls int `json:"numCalls,omitempty" db:"numCalls,omitempty"`
CallRate float32 `json:"callRate,omitempty" db:"callRate,omitempty"`
}
type ServiceMapDependencyItem struct {
SpanId string `json:"spanId,omitempty" db:"spanID,omitempty"`
ParentSpanId string `json:"parentSpanId,omitempty" db:"parentSpanID,omitempty"`
ServiceName string `json:"serviceName,omitempty" db:"serviceName,omitempty"`
SpanId string `json:"spanId,omitempty" ch:"spanID"`
ParentSpanId string `json:"parentSpanId,omitempty" ch:"parentSpanID"`
ServiceName string `json:"serviceName,omitempty" ch:"serviceName"`
}
type UsageItem struct {
Time string `json:"time,omitempty" db:"time,omitempty"`
Timestamp int64 `json:"timestamp" db:"timestamp"`
Count int64 `json:"count" db:"count"`
Time time.Time `json:"time,omitempty" ch:"time"`
Timestamp uint64 `json:"timestamp" ch:"timestamp"`
Count uint64 `json:"count" ch:"count"`
}
type TopEndpointsItem struct {
Percentile50 float32 `json:"p50" db:"p50"`
Percentile95 float32 `json:"p95" db:"p95"`
Percentile99 float32 `json:"p99" db:"p99"`
NumCalls int `json:"numCalls" db:"numCalls"`
Name string `json:"name" db:"name"`
}
type TagItem struct {
TagKeys string `json:"tagKeys" db:"tagKeys"`
TagCount int `json:"tagCount" db:"tagCount"`
Percentile50 float64 `json:"p50" ch:"p50"`
Percentile95 float64 `json:"p95" ch:"p95"`
Percentile99 float64 `json:"p99" ch:"p99"`
NumCalls uint64 `json:"numCalls" ch:"numCalls"`
Name string `json:"name" ch:"name"`
}
type TagFilters struct {
TagKeys string `json:"tagKeys" db:"tagKeys"`
TagKeys string `json:"tagKeys" ch:"tagKeys"`
}
type TagValues struct {
TagValues string `json:"tagValues" db:"tagValues"`
TagValues string `json:"tagValues" ch:"tagValues"`
}
type ServiceMapDependencyResponseItem struct {
Parent string `json:"parent,omitempty" db:"parent,omitempty"`
Child string `json:"child,omitempty" db:"child,omitempty"`
CallCount int `json:"callCount,omitempty" db:"callCount,omitempty"`
}
type SpanSearchAggregatesResponseItem struct {
Timestamp int64 `json:"timestamp,omitempty" db:"timestamp" `
Time string `json:"time,omitempty" db:"time"`
Value float32 `json:"value,omitempty" db:"value"`
Parent string `json:"parent,omitempty" ch:"parent"`
Child string `json:"child,omitempty" ch:"child"`
CallCount int `json:"callCount,omitempty" ch:"callCount"`
}
type GetFilteredSpansAggregatesResponse struct {
@ -267,10 +232,11 @@ type SpanAggregatesResponseItem struct {
GroupBy map[string]float32 `json:"groupBy,omitempty"`
}
type SpanAggregatesDBResponseItem struct {
Timestamp int64 `json:"timestamp,omitempty" db:"timestamp" `
Time string `json:"time,omitempty" db:"time"`
Value float32 `json:"value,omitempty" db:"value"`
GroupBy sql.NullString `json:"groupBy,omitempty" db:"groupBy"`
Timestamp int64 `ch:"timestamp" `
Time time.Time `ch:"time"`
Value uint64 `ch:"value"`
FloatValue float32 `ch:"floatValue"`
GroupBy string `ch:"groupBy"`
}
type SetTTLResponseItem struct {
@ -283,7 +249,7 @@ type DiskItem struct {
}
type DBResponseTTL struct {
EngineFull string `db:"engine_full"`
EngineFull string `ch:"engine_full"`
}
type GetTTLResponseItem struct {
@ -293,90 +259,81 @@ type GetTTLResponseItem struct {
TracesMoveTime int `json:"traces_move_ttl_duration_hrs,omitempty"`
}
type DBResponseMinMaxDuration struct {
MinDuration int `db:"min(durationNano)"`
MaxDuration int `db:"max(durationNano)"`
}
type DBResponseServiceName struct {
ServiceName string `db:"serviceName"`
Count int `db:"count"`
ServiceName string `ch:"serviceName"`
Count uint64 `ch:"count"`
}
type DBResponseHttpCode struct {
HttpCode string `db:"httpCode"`
Count int `db:"count"`
HttpCode string `ch:"httpCode"`
Count uint64 `ch:"count"`
}
type DBResponseHttpRoute struct {
HttpRoute string `db:"httpRoute"`
Count int `db:"count"`
HttpRoute string `ch:"httpRoute"`
Count uint64 `ch:"count"`
}
type DBResponseHttpUrl struct {
HttpUrl string `db:"httpUrl"`
Count int `db:"count"`
HttpUrl string `ch:"httpUrl"`
Count uint64 `ch:"count"`
}
type DBResponseHttpMethod struct {
HttpMethod string `db:"httpMethod"`
Count int `db:"count"`
HttpMethod string `ch:"httpMethod"`
Count uint64 `ch:"count"`
}
type DBResponseHttpHost struct {
HttpHost string `db:"httpHost"`
Count int `db:"count"`
HttpHost string `ch:"httpHost"`
Count uint64 `ch:"count"`
}
type DBResponseOperation struct {
Operation string `db:"name"`
Count int `db:"count"`
Operation string `ch:"name"`
Count uint64 `ch:"count"`
}
type DBResponseComponent struct {
Component sql.NullString `db:"component"`
Count int `db:"count"`
}
type DBResponseErrors struct {
NumErrors int `db:"numErrors"`
Component string `ch:"component"`
Count uint64 `ch:"count"`
}
type DBResponseTotal struct {
NumTotal int `db:"numTotal"`
NumTotal uint64 `ch:"numTotal"`
}
type SpanFiltersResponse struct {
ServiceName map[string]int `json:"serviceName"`
Status map[string]int `json:"status"`
Duration map[string]int `json:"duration"`
Operation map[string]int `json:"operation"`
HttpCode map[string]int `json:"httpCode"`
HttpUrl map[string]int `json:"httpUrl"`
HttpMethod map[string]int `json:"httpMethod"`
HttpRoute map[string]int `json:"httpRoute"`
HttpHost map[string]int `json:"httpHost"`
Component map[string]int `json:"component"`
ServiceName map[string]uint64 `json:"serviceName"`
Status map[string]uint64 `json:"status"`
Duration map[string]uint64 `json:"duration"`
Operation map[string]uint64 `json:"operation"`
HttpCode map[string]uint64 `json:"httpCode"`
HttpUrl map[string]uint64 `json:"httpUrl"`
HttpMethod map[string]uint64 `json:"httpMethod"`
HttpRoute map[string]uint64 `json:"httpRoute"`
HttpHost map[string]uint64 `json:"httpHost"`
Component map[string]uint64 `json:"component"`
}
type Error struct {
ExceptionType string `json:"exceptionType" db:"exceptionType"`
ExceptionMsg string `json:"exceptionMessage" db:"exceptionMessage"`
ExceptionCount int64 `json:"exceptionCount" db:"exceptionCount"`
LastSeen time.Time `json:"lastSeen" db:"lastSeen"`
FirstSeen time.Time `json:"firstSeen" db:"firstSeen"`
ServiceName string `json:"serviceName" db:"serviceName"`
ExceptionType string `json:"exceptionType" ch:"exceptionType"`
ExceptionMsg string `json:"exceptionMessage" ch:"exceptionMessage"`
ExceptionCount int64 `json:"exceptionCount" ch:"exceptionCount"`
LastSeen time.Time `json:"lastSeen" ch:"lastSeen"`
FirstSeen time.Time `json:"firstSeen" ch:"firstSeen"`
ServiceName string `json:"serviceName" ch:"serviceName"`
}
type ErrorWithSpan struct {
ErrorID string `json:"errorId" db:"errorID"`
ExceptionType string `json:"exceptionType" db:"exceptionType"`
ExcepionStacktrace string `json:"excepionStacktrace" db:"excepionStacktrace"`
ExceptionEscaped string `json:"exceptionEscaped" db:"exceptionEscaped"`
ExceptionMsg string `json:"exceptionMessage" db:"exceptionMessage"`
Timestamp time.Time `json:"timestamp" db:"timestamp"`
SpanID string `json:"spanID" db:"spanID"`
TraceID string `json:"traceID" db:"traceID"`
ServiceName string `json:"serviceName" db:"serviceName"`
NewerErrorID string `json:"newerErrorId" db:"newerErrorId"`
OlderErrorID string `json:"olderErrorId" db:"olderErrorId"`
ErrorID string `json:"errorId" ch:"errorID"`
ExceptionType string `json:"exceptionType" ch:"exceptionType"`
ExcepionStacktrace string `json:"excepionStacktrace" ch:"excepionStacktrace"`
ExceptionEscaped string `json:"exceptionEscaped" ch:"exceptionEscaped"`
ExceptionMsg string `json:"exceptionMessage" ch:"exceptionMessage"`
Timestamp time.Time `json:"timestamp" ch:"timestamp"`
SpanID string `json:"spanID" ch:"spanID"`
TraceID string `json:"traceID" ch:"traceID"`
ServiceName string `json:"serviceName" ch:"serviceName"`
NewerErrorID string `json:"newerErrorId" ch:"newerErrorId"`
OlderErrorID string `json:"olderErrorId" ch:"olderErrorId"`
}

View File

@ -2,8 +2,8 @@ package telemetry
func IgnoredPaths() map[string]struct{} {
ignoredPaths := map[string]struct{}{
"/api/v1/tags": struct{}{},
"/api/v1/version": struct{}{},
"/api/v1/tags": {},
"/api/v1/version": {},
}
return ignoredPaths