Merge remote-tracking branch 'origin/master' into zoltan/span-marker-fix

This commit is contained in:
Zoltán Bedi
2021-02-23 17:29:35 +01:00
28 changed files with 239 additions and 117 deletions
+18 -18
View File
@@ -17,7 +17,7 @@ steps:
image: grafana/build-container:1.3.2
commands:
- mkdir -p bin
- curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v0.5.38/grabpl
- curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v0.5.43/grabpl
- chmod +x bin/grabpl
- ./bin/grabpl verify-drone
- curl -fLO https://github.com/jwilder/dockerize/releases/download/v$${DOCKERIZE_VERSION}/dockerize-linux-amd64-v$${DOCKERIZE_VERSION}.tar.gz
@@ -259,7 +259,7 @@ steps:
image: grafana/build-container:1.3.2
commands:
- mkdir -p bin
- curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v0.5.38/grabpl
- curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v0.5.43/grabpl
- chmod +x bin/grabpl
- ./bin/grabpl verify-drone
- curl -fLO https://github.com/jwilder/dockerize/releases/download/v$${DOCKERIZE_VERSION}/dockerize-linux-amd64-v$${DOCKERIZE_VERSION}.tar.gz
@@ -591,7 +591,7 @@ steps:
image: grafana/ci-wix:0.1.1
commands:
- $$ProgressPreference = "SilentlyContinue"
- Invoke-WebRequest https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v0.5.38/windows/grabpl.exe -OutFile grabpl.exe
- Invoke-WebRequest https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v0.5.43/windows/grabpl.exe -OutFile grabpl.exe
- .\grabpl.exe verify-drone
- name: build-windows-installer
@@ -641,7 +641,7 @@ steps:
image: grafana/build-container:1.3.2
commands:
- mkdir -p bin
- curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v0.5.38/grabpl
- curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v0.5.43/grabpl
- chmod +x bin/grabpl
- ./bin/grabpl verify-drone
environment:
@@ -726,7 +726,7 @@ steps:
image: grafana/build-container:1.3.2
commands:
- mkdir -p bin
- curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v0.5.38/grabpl
- curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v0.5.43/grabpl
- chmod +x bin/grabpl
- ./bin/grabpl verify-drone
- ./bin/grabpl verify-version ${DRONE_TAG}
@@ -1033,7 +1033,7 @@ steps:
image: grafana/ci-wix:0.1.1
commands:
- $$ProgressPreference = "SilentlyContinue"
- Invoke-WebRequest https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v0.5.38/windows/grabpl.exe -OutFile grabpl.exe
- Invoke-WebRequest https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v0.5.43/windows/grabpl.exe -OutFile grabpl.exe
- .\grabpl.exe verify-drone
- name: build-windows-installer
@@ -1084,7 +1084,7 @@ steps:
image: grafana/build-container:1.3.2
commands:
- mkdir -p bin
- curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v0.5.38/grabpl
- curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v0.5.43/grabpl
- chmod +x bin/grabpl
- git clone "https://$${GITHUB_TOKEN}@github.com/grafana/grafana-enterprise.git"
- cd grafana-enterprise
@@ -1474,7 +1474,7 @@ steps:
image: grafana/ci-wix:0.1.1
commands:
- $$ProgressPreference = "SilentlyContinue"
- Invoke-WebRequest https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v0.5.38/windows/grabpl.exe -OutFile grabpl.exe
- Invoke-WebRequest https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v0.5.43/windows/grabpl.exe -OutFile grabpl.exe
- git clone "https://$$env:GITHUB_TOKEN@github.com/grafana/grafana-enterprise.git"
- cd grafana-enterprise
- git checkout ${DRONE_TAG}
@@ -1540,7 +1540,7 @@ steps:
image: grafana/build-container:1.3.2
commands:
- mkdir -p bin
- curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v0.5.38/grabpl
- curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v0.5.43/grabpl
- chmod +x bin/grabpl
- ./bin/grabpl verify-drone
- ./bin/grabpl verify-version ${DRONE_TAG}
@@ -1645,7 +1645,7 @@ steps:
image: grafana/build-container:1.3.2
commands:
- mkdir -p bin
- curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v0.5.38/grabpl
- curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v0.5.43/grabpl
- chmod +x bin/grabpl
- ./bin/grabpl verify-drone
- ./bin/grabpl verify-version v7.3.0-test
@@ -1941,7 +1941,7 @@ steps:
image: grafana/ci-wix:0.1.1
commands:
- $$ProgressPreference = "SilentlyContinue"
- Invoke-WebRequest https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v0.5.38/windows/grabpl.exe -OutFile grabpl.exe
- Invoke-WebRequest https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v0.5.43/windows/grabpl.exe -OutFile grabpl.exe
- .\grabpl.exe verify-drone
- name: build-windows-installer
@@ -1992,7 +1992,7 @@ steps:
image: grafana/build-container:1.3.2
commands:
- mkdir -p bin
- curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v0.5.38/grabpl
- curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v0.5.43/grabpl
- chmod +x bin/grabpl
- git clone "https://$${GITHUB_TOKEN}@github.com/grafana/grafana-enterprise.git"
- cd grafana-enterprise
@@ -2376,7 +2376,7 @@ steps:
image: grafana/ci-wix:0.1.1
commands:
- $$ProgressPreference = "SilentlyContinue"
- Invoke-WebRequest https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v0.5.38/windows/grabpl.exe -OutFile grabpl.exe
- Invoke-WebRequest https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v0.5.43/windows/grabpl.exe -OutFile grabpl.exe
- git clone "https://$$env:GITHUB_TOKEN@github.com/grafana/grafana-enterprise.git"
- cd grafana-enterprise
- git checkout master
@@ -2442,7 +2442,7 @@ steps:
image: grafana/build-container:1.3.2
commands:
- mkdir -p bin
- curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v0.5.38/grabpl
- curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v0.5.43/grabpl
- chmod +x bin/grabpl
- ./bin/grabpl verify-drone
- ./bin/grabpl verify-version v7.3.0-test
@@ -2547,7 +2547,7 @@ steps:
image: grafana/build-container:1.3.2
commands:
- mkdir -p bin
- curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v0.5.38/grabpl
- curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v0.5.43/grabpl
- chmod +x bin/grabpl
- ./bin/grabpl verify-drone
- curl -fLO https://github.com/jwilder/dockerize/releases/download/v$${DOCKERIZE_VERSION}/dockerize-linux-amd64-v$${DOCKERIZE_VERSION}.tar.gz
@@ -2818,7 +2818,7 @@ steps:
image: grafana/ci-wix:0.1.1
commands:
- $$ProgressPreference = "SilentlyContinue"
- Invoke-WebRequest https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v0.5.38/windows/grabpl.exe -OutFile grabpl.exe
- Invoke-WebRequest https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v0.5.43/windows/grabpl.exe -OutFile grabpl.exe
- .\grabpl.exe verify-drone
- name: build-windows-installer
@@ -2865,7 +2865,7 @@ steps:
image: grafana/build-container:1.3.2
commands:
- mkdir -p bin
- curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v0.5.38/grabpl
- curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v0.5.43/grabpl
- chmod +x bin/grabpl
- git clone "https://$${GITHUB_TOKEN}@github.com/grafana/grafana-enterprise.git"
- cd grafana-enterprise
@@ -3252,7 +3252,7 @@ steps:
image: grafana/ci-wix:0.1.1
commands:
- $$ProgressPreference = "SilentlyContinue"
- Invoke-WebRequest https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v0.5.38/windows/grabpl.exe -OutFile grabpl.exe
- Invoke-WebRequest https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v0.5.43/windows/grabpl.exe -OutFile grabpl.exe
- git clone "https://$$env:GITHUB_TOKEN@github.com/grafana/grafana-enterprise.git"
- cd grafana-enterprise
- git checkout $$env:DRONE_BRANCH
+3
View File
@@ -27,6 +27,9 @@ go.sum @grafana/backend-platform
/pkg/tsdb/azuremonitor @grafana/cloud-datasources
/pkg/tsdb/cloudmonitoring @grafana/cloud-datasources
# Database migrations
/pkg/services/sqlstore/migrations @grafana/backend-platform @grafana/hosted-grafana-team
*_mig.go @grafana/backend-platform @grafana/hosted-grafana-team
# Backend code docs
/contribute/style-guides/backend.md @grafana/backend-platform
+2 -6
View File
@@ -4,7 +4,7 @@
-include local/Makefile
.PHONY: all deps-go deps-js deps build-go build-server build-cli build-js build build-docker-dev build-docker-full lint-go revive golangci-lint tidy-check test-go test-js test run run-frontend clean devenv devenv-down revive-strict protobuf help
.PHONY: all deps-go deps-js deps build-go build-server build-cli build-js build build-docker-dev build-docker-full lint-go revive golangci-lint test-go test-js test run run-frontend clean devenv devenv-down revive-strict protobuf help
GO = GO111MODULE=on go
GO_FILES ?= ./pkg/...
@@ -95,11 +95,7 @@ golangci-lint: scripts/go/bin/golangci-lint
--config ./scripts/go/configs/.golangci.toml \
$(GO_FILES)
tidy-check:
@echo "check whether go.mod and go.sum are consistent"
@scripts/tidy-check.sh
lint-go: golangci-lint revive revive-strict tidy-check # Run all code checks for backend.
lint-go: golangci-lint revive revive-strict # Run all code checks for backend.
# with disabled SC1071 we are ignored some TCL,Expect `/usr/bin/env expect` scripts
shellcheck: $(SH_FILES) ## Run checks for shell scripts.
+14 -1
View File
@@ -32,6 +32,19 @@ datasources:
timeInterval: "15s"
secureJsonData:
password: grafana
- name: gdev-influxdb2
type: influxdb
access: proxy
url: http://localhost:8087
user: grafana
secureJsonData:
token: mytoken
password: grafana12345
jsonData:
version: Flux
organization: myorg
defaultBucket: mybucket
- name: gdev-influxdb-telegraf
type: influxdb
@@ -43,7 +56,7 @@ datasources:
timeInterval: "10s"
secureJsonData:
password: grafana
- name: gdev-opentsdb
type: opentsdb
access: proxy
+11
View File
@@ -34,6 +34,17 @@ datasources:
secureJsonData:
password: grafana
- name: gdev-influxdb2
type: influxdb
access: proxy
url: http://influxdb2:8086
secureJsonData:
token: mytoken
jsonData:
version: Flux
organization: myorg
defaultBucket: mybucket
- name: gdev-influxdb-telegraf
type: influxdb
access: proxy
@@ -1,39 +1,40 @@
influxdb:
influxdb2:
image: quay.io/influxdb/influxdb:v2.0.3
container_name: influxdb2
ports:
- '8086:8086'
- '8087:8086'
environment:
INFLUXDB_REPORTING_DISABLED: 'true'
volumes:
- ./docker/blocks/influxdb2/influxdb.conf:/etc/influxdb/influxdb.conf
# Use the influx cli to set up an influxdb instance.
influxdb_cli:
influxdb2_cli:
links:
- influxdb
- influxdb2
image: quay.io/influxdb/influxdb:v2.0.3
# Use these same configurations parameters in your telegraf configuration, mytelegraf.conf.
entrypoint: influx setup --bucket mybucket -t mytoken -o myorg --username=grafana --password=grafana12345 --host=http://influxdb:8086 -f
entrypoint: influx setup --bucket mybucket -t mytoken -o myorg --username=grafana --password=grafana12345 --host=http://influxdb2:8086 -f
# Wait for the influxd service in the influxdb container has fully bootstrapped before trying to setup an influxdb instance with the influxdb_cli service.
restart: on-failure:10
depends_on:
- influxdb
- influxdb2
fake-influxdb-data:
fake-influxdb2-data:
image: grafana/fake-data-gen
links:
- influxdb
- influxdb2
environment:
FD_SERVER: influxdb2
FD_DATASOURCE: influxdb
FD_PORT: 8086
telegraf:
telegraf2:
image: telegraf
links:
- influxdb
- influxdb2
depends_on:
- influxdb_cli
- influxdb2_cli
volumes:
- ./docker/blocks/influxdb2/telegraf.conf:/etc/telegraf/telegraf.conf:ro
- /var/log:/var/log
+1 -1
View File
@@ -90,7 +90,7 @@
## urls will be written to each interval.
# urls = ["unix:///var/run/influxdb.sock"]
# urls = ["udp://127.0.0.1:8089"]
urls = ["http://influxdb:8086"]
urls = ["http://influxdb2:8086"]
token = "mytoken"
organization = "myorg"
bucket = "mybucket"
-4
View File
@@ -217,10 +217,6 @@ Once these two properties are set, you can send the alerts to Kafka for further
Notifications can be sent by setting up an incoming webhook in Google Hangouts chat. For more information about configuring a webhook, refer to [webhooks](https://developers.google.com/hangouts/chat/how-tos/webhooks).
### Squadcast
Squadcast helps you get alerted via Phone call, SMS, Email and Push notifications and lets you take actions on those alerts. Grafana notifications can be sent to Squadcast via a simple incoming webhook. Refer the official [Squadcast support documentation](https://support.squadcast.com/docs/grafana) for configuring these webhooks.
### Prometheus Alertmanager
Alertmanager handles alerts sent by client applications such as Prometheus server or Grafana. It takes care of deduplicating, grouping, and routing them to the correct receiver. Grafana notifications can be sent to Alertmanager via a simple incoming webhook. Refer to the official [Prometheus Alertmanager documentation](https://prometheus.io/docs/alerting/alertmanager) for configuration information.
+1
View File
@@ -9,5 +9,6 @@ export * from './types';
export * from './measurement';
export { loadPluginCss, SystemJS, PluginCssOptions } from './utils/plugin';
export { reportMetaAnalytics } from './utils/analytics';
export { logInfo, logDebug, logWarning, logError } from './utils/logging';
export { DataSourceWithBackend, HealthCheckResult, HealthStatus } from './utils/DataSourceWithBackend';
export { toDataQueryError, toDataQueryResponse, frameToMetricFindValue } from './utils/queryResponse';
@@ -0,0 +1,50 @@
import { captureMessage, captureException, Severity as LogLevel } from '@sentry/browser';
export { LogLevel };
// a bit stricter than what Sentry allows
type Contexts = Record<string, Record<string, number | string | Record<string, string | number>>>;
/**
* Log a message at INFO level. Depending on configuration might be forwarded to backend and logged to stdout or sent to Sentry
*
* @public
*/
export function logInfo(message: string, contexts?: Contexts) {
captureMessage(message, {
level: LogLevel.Info,
contexts,
});
}
/**
* Log a message at WARNING level. Depending on configuration might be forwarded to backend and logged to stdout or sent to Sentry
*
* @public
*/
export function logWarning(message: string, contexts?: Contexts) {
captureMessage(message, {
level: LogLevel.Warning,
contexts,
});
}
/**
* Log a message at DEBUG level. Depending on configuration might be forwarded to backend and logged to stdout or sent to Sentry
*
* @public
*/
export function logDebug(message: string, contexts?: Contexts) {
captureMessage(message, {
level: LogLevel.Debug,
contexts,
});
}
/**
* Log an error. Depending on configuration might be forwarded to backend and logged to stdout or sent to Sentry
*
* @public
*/
export function logError(err: Error, contexts?: Contexts) {
captureException(err, { contexts });
}
@@ -59,5 +59,3 @@ export const parameters = {
escapeHTML: false,
},
};
export const NOOP_CONTROL = { control: { disable: true } };
@@ -1,7 +1,7 @@
import React from 'react';
import { Story } from '@storybook/react';
import { BarGauge, BarGaugeDisplayMode } from '@grafana/ui';
import { NOOP_CONTROL } from '@grafana/ui/.storybook/preview';
import { NOOP_CONTROL } from '../../utils/storybook/noopControl';
import { VizOrientation, ThresholdsMode, Field, FieldType, getDisplayProcessor } from '@grafana/data';
import { Props } from './BarGauge';
import { withCenteredStory } from '../../utils/storybook/withCenteredStory';
@@ -11,7 +11,7 @@ import {
import { withCenteredStory } from '../../utils/storybook/withCenteredStory';
import mdx from './BigValue.mdx';
import { useTheme } from '../../themes';
import { NOOP_CONTROL } from '@grafana/ui/.storybook/preview';
import { NOOP_CONTROL } from '../../utils/storybook/noopControl';
import { ArrayVector, FieldSparkline, FieldType } from '@grafana/data';
export default {
@@ -2,7 +2,7 @@ import React from 'react';
import { Story } from '@storybook/react';
import { withCenteredStory } from '../../utils/storybook/withCenteredStory';
import { ButtonCascader } from '@grafana/ui';
import { NOOP_CONTROL } from '@grafana/ui/.storybook/preview';
import { NOOP_CONTROL } from '../../utils/storybook/noopControl';
import { ButtonCascaderProps } from './ButtonCascader';
export default {
@@ -1,7 +1,7 @@
import React from 'react';
import { renderComponentWithTheme } from '../../utils/storybook/withTheme';
import { CallToActionCard, CallToActionCardProps } from './CallToActionCard';
import { NOOP_CONTROL } from '../../../.storybook/preview';
import { NOOP_CONTROL } from '../../utils/storybook/noopControl';
import { Story } from '@storybook/react';
import { Button } from '../Button/Button';
import { action } from '@storybook/addon-actions';
@@ -1,6 +1,6 @@
import { Story } from '@storybook/react';
import { withCenteredStory } from '../../utils/storybook/withCenteredStory';
import { NOOP_CONTROL } from '../../../.storybook/preview';
import { NOOP_CONTROL } from '../../utils/storybook/noopControl';
import { Cascader } from '@grafana/ui';
import { CascaderProps } from './Cascader';
import mdx from './Cascader.mdx';
@@ -0,0 +1 @@
export const NOOP_CONTROL = { control: { disable: true } };
+1 -9
View File
@@ -1,12 +1,4 @@
{
"exclude": [
"**/*.story.tsx",
"**/*.story.internal.tsx",
"**/*.test.ts*",
"**/*.tmpl.ts",
"dist",
"node_modules",
"src/utils/storybook"
],
"exclude": ["**/*.story.tsx", "**/*.test.ts*", "**/*.tmpl.ts", "dist", "node_modules", "src/utils/storybook"],
"extends": "./tsconfig.json"
}
+2 -2
View File
@@ -245,8 +245,8 @@ func (proxy *DataSourceProxy) validateRequest() error {
if proxy.ctx.Req.Request.Method == "PUT" {
return errors.New("puts not allowed on proxied Prometheus datasource")
}
if proxy.ctx.Req.Request.Method == "POST" && !(proxy.proxyPath == "api/v1/query" || proxy.proxyPath == "api/v1/query_range") {
return errors.New("posts not allowed on proxied Prometheus datasource except on /query and /query_range")
if proxy.ctx.Req.Request.Method == "POST" && !(proxy.proxyPath == "api/v1/query" || proxy.proxyPath == "api/v1/query_range" || proxy.proxyPath == "api/v1/series" || proxy.proxyPath == "api/v1/labels") {
return errors.New("posts not allowed on proxied Prometheus datasource except on /query, /query_range, /series and /labels")
}
}
+2 -2
View File
@@ -60,7 +60,7 @@ var metricsMap = map[string][]string{
"AWS/Cognito": {"AccountTakeOverRisk", "CompromisedCredentialsRisk", "NoRisk", "OverrideBlock", "Risk"},
"AWS/Connect": {"CallBackNotDialableNumber", "CallRecordingUploadError", "CallsBreachingConcurrencyQuota", "CallsPerInterval", "ConcurrentCalls", "ConcurrentCallsPercentage", "ContactFlowErrors", "ContactFlowFatalErrors", "LongestQueueWaitTime", "MisconfiguredPhoneNumbers", "MissedCalls", "PublicSigningKeyUsage", "QueueCapacityExceededError", "QueueSize", "ThrottledCalls", "ToInstancePacketLossRate"},
"AWS/DataSync": {"BytesVerifiedSource", "BytesPreparedSource", "FilesVerifiedSource", "FilesPreparedSource", "BytesVerifiedDestination", "BytesPreparedDestination", "FilesVerifiedDestination", "FilesPreparedDestination", "FilesTransferred", "BytesTransferred", "BytesWritten"},
"AWS/DDoSProtection": {"DDoSDetected", "DDoSAttackBitsPerSecond", "DDoSAttackPacketsPerSecond", "DDoSAttackRequestsPerSecond"},
"AWS/DDoSProtection": {"DDoSDetected", "DDoSAttackBitsPerSecond", "DDoSAttackPacketsPerSecond", "DDoSAttackRequestsPerSecond", "VolumeBitsPerSecond", "VolumePacketsPerSecond"},
"AWS/DMS": {"CDCChangesDiskSource", "CDCChangesDiskTarget", "CDCChangesMemorySource", "CDCChangesMemoryTarget", "CDCIncomingChanges", "CDCLatencySource", "CDCLatencyTarget", "CDCThroughputBandwidthSource", "CDCThroughputBandwidthTarget", "CDCThroughputRowsSource", "CDCThroughputRowsTarget", "CPUUtilization", "FreeStorageSpace", "FreeableMemory", "FullLoadThroughputBandwidthSource", "FullLoadThroughputBandwidthTarget", "FullLoadThroughputRowsSource", "FullLoadThroughputRowsTarget", "NetworkReceiveThroughput", "NetworkTransmitThroughput", "ReadIOPS", "ReadLatency", "ReadThroughput", "SwapUsage", "WriteIOPS", "WriteLatency", "WriteThroughput"},
"AWS/DocDB": {"BackupRetentionPeriodStorageUsed", "BufferCacheHitRatio", "ChangeStreamLogSize", "CPUUtilization", "DatabaseConnections", "DBInstanceReplicaLag", "DBClusterReplicaLagMaximum", "DBClusterReplicaLagMinimum", "DiskQueueDepth", "EngineUptime", "FreeableMemory", "FreeLocalStorage", "NetworkReceiveThroughput", "NetworkThroughput", "NetworkTransmitThroughput", "ReadIOPS", "ReadLatency", "ReadThroughput", "SnapshotStorageUsed", "SwapUsage", "TotalBackupStorageBilled", "VolumeBytesUsed", "VolumeReadIOPs", "VolumeWriteIOPs", "WriteIOPS", "WriteLatency", "WriteThroughput"},
"AWS/DX": {"ConnectionBpsEgress", "ConnectionBpsIngress", "ConnectionErrorCount", "ConnectionCRCErrorCount", "ConnectionLightLevelRx", "ConnectionLightLevelTx", "ConnectionPpsEgress", "ConnectionPpsIngress", "ConnectionState", "VirtualInterfaceBpsEgress", "VirtualInterfaceBpsIngress", "VirtualInterfacePpsEgress", "VirtualInterfacePpsIngress"},
@@ -156,7 +156,7 @@ var dimensionsMap = map[string][]string{
"AWS/Cognito": {"Operation", "RiskLevel", "UserPoolId"},
"AWS/Connect": {"InstanceId", "MetricGroup", "Participant", "QueueName", "Stream Type", "Type of Connection"},
"AWS/DataSync": {"AgentId", "TaskId"},
"AWS/DDoSProtection": {"ResourceArn", "AttackVector"},
"AWS/DDoSProtection": {"ResourceArn", "AttackVector", "MitigationAction", "Protocol", "SourcePort", "DestinationPort", "SourceIp", "SourceAsn", "TcpFlags"},
"AWS/DMS": {"ReplicationInstanceIdentifier", "ReplicationTaskIdentifier"},
"AWS/DocDB": {"DBClusterIdentifier", "DBInstanceIdentifier", "Role"},
"AWS/DX": {"ConnectionId", "OpticalLaneNumber", "VirtualInterfaceId"},
+62 -16
View File
@@ -30,18 +30,19 @@ type columnInfo struct {
// frameBuilder is an interface to help testing.
type frameBuilder struct {
tableID int64
active *data.Frame
frames []*data.Frame
value *data.FieldConverter
columns []columnInfo
labels []string
maxPoints int // max points in a series
maxSeries int // max number of series
totalSeries int
isTimeSeries bool
timeColumn string // sometimes it is not `_time`
timeDisplay string
currentGroupKey []interface{}
groupKeyColumnNames []string
active *data.Frame
frames []*data.Frame
value *data.FieldConverter
columns []columnInfo
labels []string
maxPoints int // max points in a series
maxSeries int // max number of series
totalSeries int
isTimeSeries bool
timeColumn string // sometimes it is not `_time`
timeDisplay string
}
func isTag(schk string) bool {
@@ -95,11 +96,18 @@ func getConverter(t string) (*data.FieldConverter, error) {
func (fb *frameBuilder) Init(metadata *query.FluxTableMetadata) error {
columns := metadata.Columns()
fb.frames = make([]*data.Frame, 0)
fb.tableID = -1
fb.currentGroupKey = nil
fb.value = nil
fb.columns = make([]columnInfo, 0)
fb.isTimeSeries = false
fb.timeColumn = ""
fb.groupKeyColumnNames = make([]string, 0)
for _, col := range columns {
if col.IsGroup() {
fb.groupKeyColumnNames = append(fb.groupKeyColumnNames, col.Name())
}
}
for _, col := range columns {
switch {
@@ -175,14 +183,52 @@ func getTimeSeriesTimeColumn(columns []*query.FluxColumn) *query.FluxColumn {
return nil
}
func getTableID(record *query.FluxRecord, groupColumns []string) []interface{} {
result := make([]interface{}, len(groupColumns))
// Flux does not allow duplicate column-names,
// so we can be sure there is no confusion in the record.
//
// ( it does allow for a column named "table" to exist,
// and shadow the table-id "table" column, but the potentially
// shadowed table-id column is not a part of the group-key,
// so we should be safe )
for i, colName := range groupColumns {
result[i] = record.ValueByKey(colName)
}
return result
}
func isTableIDEqual(id1 []interface{}, id2 []interface{}) bool {
if (id1 == nil) || (id2 == nil) {
return false
}
if len(id1) != len(id2) {
return false
}
for i, id1Val := range id1 {
id2Val := id2[i]
if id1Val != id2Val {
return false
}
}
return true
}
// Append appends a single entry from an influxdb2 record to a data frame
// Values are appended to _value
// Tags are appended as labels
// _measurement holds the dataframe name
// _field holds the field name.
func (fb *frameBuilder) Append(record *query.FluxRecord) error {
table, ok := record.ValueByKey("table").(int64)
if ok && table != fb.tableID {
table := getTableID(record, fb.groupKeyColumnNames)
if (fb.currentGroupKey == nil) || !isTableIDEqual(table, fb.currentGroupKey) {
fb.totalSeries++
if fb.totalSeries > fb.maxSeries {
return fmt.Errorf("results are truncated, max series reached (%d)", fb.maxSeries)
@@ -226,7 +272,7 @@ func (fb *frameBuilder) Append(record *query.FluxRecord) error {
}
fb.frames = append(fb.frames, fb.active)
fb.tableID = table
fb.currentGroupKey = table
}
if fb.isTimeSeries {
+5
View File
@@ -103,6 +103,11 @@ func TestExecuteMultiple(t *testing.T) {
fmt.Println("----------------------")
}
func TestExecuteColumnNamedTable(t *testing.T) {
dr := verifyGoldenResponse(t, "table")
require.Len(t, dr.Frames, 1)
}
func TestExecuteGrouping(t *testing.T) {
dr := verifyGoldenResponse(t, "grouping")
require.Len(t, dr.Frames, 3)
+6
View File
@@ -0,0 +1,6 @@
#group,false,false,true,true,false,false,true
#datatype,string,long,dateTime:RFC3339,dateTime:RFC3339,dateTime:RFC3339,long,string
#default,last,,,,,,
,result,table,_start,_stop,_time,_value,table
,,0,2021-02-05T14:02:04.7009051Z,2021-02-05T14:03:04.7009051Z,2021-02-05T14:03:04.7009051Z,42,something
1 #group false false true true false false true
2 #datatype string long dateTime:RFC3339 dateTime:RFC3339 dateTime:RFC3339 long string
3 #default last
4 result table _start _stop _time _value table
5 0 2021-02-05T14:02:04.7009051Z 2021-02-05T14:03:04.7009051Z 2021-02-05T14:03:04.7009051Z 42 something
+16
View File
@@ -0,0 +1,16 @@
🌟 This was machine generated. Do not edit. 🌟
Frame[0] {}
Name:
Dimensions: 2 Fields by 1 Rows
+---------------------------------------+----------------+
| Name: Time | Name: |
| Labels: | Labels: |
| Type: []time.Time | Type: []*int64 |
+---------------------------------------+----------------+
| 2021-02-05 14:03:04.7009051 +0000 UTC | 42 |
+---------------------------------------+----------------+
====== TEST DATA RESPONSE (arrow base64) ======
FRAME=QVJST1cxAAD/////yAEAABAAAAAAAAoADgAMAAsABAAKAAAAFAAAAAAAAAEDAAoADAAAAAgABAAKAAAACAAAAHQAAAADAAAATAAAACgAAAAEAAAAzP7//wgAAAAMAAAAAAAAAAAAAAAFAAAAcmVmSWQAAADs/v//CAAAAAwAAAAAAAAAAAAAAAQAAABuYW1lAAAAAAz///8IAAAADAAAAAIAAAB7fQAABAAAAG1ldGEAAAAAAgAAALAAAAAYAAAAAAASABgAFAATABIADAAAAAgABAASAAAAFAAAAFwAAABkAAAAAAACAWgAAAACAAAAKAAAAAQAAABw////CAAAAAwAAAAAAAAAAAAAAAQAAABuYW1lAAAAAJD///8IAAAADAAAAAIAAAB7fQAABgAAAGxhYmVscwAAAAAAAAgADAAIAAcACAAAAAAAAAFAAAAAAAAAAAAAEgAYABQAAAATAAwAAAAIAAQAEgAAABQAAABEAAAATAAAAAAAAApMAAAAAQAAAAwAAAAIAAwACAAEAAgAAAAIAAAAEAAAAAQAAABUaW1lAAAAAAQAAABuYW1lAAAAAAAAAAAAAAYACAAGAAYAAAAAAAMABAAAAFRpbWUAAAAAAAAAAP////+4AAAAFAAAAAAAAAAMABYAFAATAAwABAAMAAAAEAAAAAAAAAAUAAAAAAAAAwMACgAYAAwACAAEAAoAAAAUAAAAWAAAAAEAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAgAAAAAAAAAAAAAAAIAAAABAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAIzmaQHv3mAWKgAAAAAAAAAQAAAADAAUABIADAAIAAQADAAAABAAAAAsAAAAOAAAAAAAAwABAAAA2AEAAAAAAADAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAoADAAAAAgABAAKAAAACAAAAHQAAAADAAAATAAAACgAAAAEAAAAzP7//wgAAAAMAAAAAAAAAAAAAAAFAAAAcmVmSWQAAADs/v//CAAAAAwAAAAAAAAAAAAAAAQAAABuYW1lAAAAAAz///8IAAAADAAAAAIAAAB7fQAABAAAAG1ldGEAAAAAAgAAALAAAAAYAAAAAAASABgAFAATABIADAAAAAgABAASAAAAFAAAAFwAAABkAAAAAAACAWgAAAACAAAAKAAAAAQAAABw////CAAAAAwAAAAAAAAAAAAAAAQAAABuYW1lAAAAAJD///8IAAAADAAAAAIAAAB7fQAABgAAAGxhYmVscwAAAAAAAAgADAAIAAcACAAAAAAAAAFAAAAAAAAAAAAAEgAYABQAAAATAAwAAAAIAAQAEgAAABQAAABEAAAATAAAAAAAAApMAAAAAQAAAAwAAAAIAAwACAAEAAgAAAAIAAAAEAAAAAQAAABUaW1lAAAAAAQAAABuYW1lAAAAAAAAAAAAAAYACAAGAAYAAAAAAAMABAAAAFRpbWUAAAAA8AEAAEFSUk9XMQ==
@@ -105,8 +105,7 @@ describe('PrometheusDatasource', () => {
expect(fetchMock.mock.calls.length).toBe(1);
expect(fetchMock.mock.calls[0][0].method).toBe('GET');
});
it('should still perform a GET request with the DS HTTP method set to POST', () => {
it('should still perform a GET request with the DS HTTP method set to POST and not POST-friendly endpoint', () => {
const postSettings = _.cloneDeep(instanceSettings);
postSettings.jsonData.httpMethod = 'POST';
const promDs = new PrometheusDatasource(postSettings, templateSrvStub as any, timeSrvStub as any);
@@ -114,6 +113,14 @@ describe('PrometheusDatasource', () => {
expect(fetchMock.mock.calls.length).toBe(1);
expect(fetchMock.mock.calls[0][0].method).toBe('GET');
});
it('should try to perform a POST request with the DS HTTP method set to POST and POST-friendly endpoint', () => {
const postSettings = _.cloneDeep(instanceSettings);
postSettings.jsonData.httpMethod = 'POST';
const promDs = new PrometheusDatasource(postSettings, templateSrvStub as any, timeSrvStub as any);
promDs.metadataRequest('api/v1/series');
expect(fetchMock.mock.calls.length).toBe(1);
expect(fetchMock.mock.calls[0][0].method).toBe('POST');
});
});
describe('When using customQueryParams', () => {
@@ -44,6 +44,7 @@ import { PrometheusVariableSupport } from './variables';
import PrometheusMetricFindQuery from './metric_find_query';
export const ANNOTATION_QUERY_STEP_DEFAULT = '60s';
const GET_AND_POST_MEDATADATA_ENDPOINTS = ['api/v1/query', 'api/v1/query_range', 'api/v1/series', 'api/v1/labels'];
export class PrometheusDatasource extends DataSourceApi<PromQuery, PromOptions> {
type: string;
@@ -136,7 +137,7 @@ export class PrometheusDatasource extends DataSourceApi<PromQuery, PromOptions>
}
// Use this for tab completion features, wont publish response to other components
metadataRequest<T = any>(url: string) {
async metadataRequest<T = any>(url: string) {
const data: any = {};
for (const [key, value] of this.customQueryParameters) {
if (data[key] == null) {
@@ -144,7 +145,21 @@ export class PrometheusDatasource extends DataSourceApi<PromQuery, PromOptions>
}
}
return this._request<T>(url, data, { method: 'GET', hideFromInspector: true }).toPromise(); // toPromise until we change getTagValues, getTagKeys to Observable
// If URL includes endpoint that supports POST and GET method, try to use configured method. This might fail as POST is supported only in v2.10+.
if (GET_AND_POST_MEDATADATA_ENDPOINTS.some((endpoint) => url.includes(endpoint))) {
try {
return await this._request<T>(url, data, { method: this.httpMethod, hideFromInspector: true }).toPromise();
} catch (err) {
// If status code of error is Method Not Allowed (405) and HTTP method is POST, retry with GET
if (this.httpMethod === 'POST' && err.status === 405) {
console.warn(`Couldn't use configured POST HTTP method for this request. Trying to use GET method instead.`);
} else {
throw err;
}
}
}
return await this._request<T>(url, data, { method: 'GET', hideFromInspector: true }).toPromise(); // toPromise until we change getTagValues, getTagKeys to Observable
}
interpolateQueryExpr(value: string | string[] = [], variable: any) {
+1 -1
View File
@@ -1,4 +1,4 @@
grabpl_version = '0.5.38'
grabpl_version = '0.5.43'
build_image = 'grafana/build-container:1.3.2'
publish_image = 'grafana/grafana-ci-deploy:1.3.1'
grafana_docker_image = 'grafana/drone-grafana-docker:0.3.2'
-35
View File
@@ -1,35 +0,0 @@
#!/bin/bash
set -eo pipefail
# Verify that Go is properly installed and available
command -v go >/dev/null 2>&1 || { echo 'please install Go or use an image that has it'; exit 1; }
backup_go_mod_files()
{
mod=$(mktemp)
cp go.mod "$mod"
sum=$(mktemp)
cp go.sum "$sum"
}
restore_go_mod_files()
{
cp "$mod" go.mod
rm "$mod"
cp "$sum" go.sum
rm "$sum"
}
# Backup current go.mod and go.sum files
backup_go_mod_files
# Defer the go.mod and go.sum files backup recovery
trap restore_go_mod_files EXIT
# Tidy go.mod and go.sum files
go mod tidy
diff "$mod" go.mod || { echo "your go.mod is inconsistent"; exit 1; }
diff "$sum" go.sum || { echo "your go.sum is inconsistent"; exit 1; }