AzureMonitor: Fix logs query multi-resource and timespan values (#67914)

* Update TimeGrain interface methods

- Make them util functions because it's simpler

* Update logs ds to appropiately set resources and timespan

* Set timespan using RCF times

* Update tests
pull/67813/head
Andreas Christou 2 years ago committed by GitHub
parent 765ae6cd90
commit 9d16718acc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      pkg/tsdb/azuremonitor/loganalytics/azure-log-analytics-datasource.go
  2. 25
      pkg/tsdb/azuremonitor/loganalytics/azure-log-analytics-datasource_test.go
  3. 3
      pkg/tsdb/azuremonitor/time/azuremonitor-time.go
  4. 8
      pkg/tsdb/azuremonitor/time/time-grain.go
  5. 8
      pkg/tsdb/azuremonitor/time/time-grain_test.go

@ -393,11 +393,15 @@ func appendErrorNotice(frame *data.Frame, err *AzureLogAnalyticsAPIError) *data.
}
func (e *AzureLogAnalyticsDatasource) createRequest(ctx context.Context, logger log.Logger, queryURL string, query *AzureLogAnalyticsQuery) (*http.Request, error) {
from := query.TimeRange.From.Format(time.RFC3339)
to := query.TimeRange.To.Format(time.RFC3339)
timespan := fmt.Sprintf("%s/%s", from, to)
body := map[string]interface{}{
"query": query.Query,
"query": query.Query,
"timespan": timespan,
}
if len(query.Resources) > 1 {
body["resources"] = query.Resources
body["workspaces"] = query.Resources
}
jsonValue, err := json.Marshal(body)
if err != nil {

@ -872,7 +872,7 @@ func TestLogAnalyticsCreateRequest(t *testing.T) {
if !cmp.Equal(req.Header, expectedHeaders) {
t.Errorf("Unexpected HTTP headers: %v", cmp.Diff(req.Header, expectedHeaders))
}
expectedBody := `{"query":"Perf"}`
expectedBody := `{"query":"Perf","timespan":"0001-01-01T00:00:00Z/0001-01-01T00:00:00Z"}`
body, err := io.ReadAll(req.Body)
require.NoError(t, err)
if !cmp.Equal(string(body), expectedBody) {
@ -887,7 +887,28 @@ func TestLogAnalyticsCreateRequest(t *testing.T) {
Query: "Perf",
})
require.NoError(t, err)
expectedBody := `{"query":"Perf","resources":["r1","r2"]}`
expectedBody := `{"query":"Perf","timespan":"0001-01-01T00:00:00Z/0001-01-01T00:00:00Z","workspaces":["r1","r2"]}`
body, err := io.ReadAll(req.Body)
require.NoError(t, err)
if !cmp.Equal(string(body), expectedBody) {
t.Errorf("Unexpected Body: %v", cmp.Diff(string(body), expectedBody))
}
})
t.Run("creates a request with timerange from query", func(t *testing.T) {
ds := AzureLogAnalyticsDatasource{}
from := time.Now()
to := from.Add(3 * time.Hour)
req, err := ds.createRequest(ctx, logger, url, &AzureLogAnalyticsQuery{
Resources: []string{"r1", "r2"},
Query: "Perf",
TimeRange: backend.TimeRange{
From: from,
To: to,
},
})
require.NoError(t, err)
expectedBody := fmt.Sprintf(`{"query":"Perf","timespan":"%s/%s","workspaces":["r1","r2"]}`, from.Format(time.RFC3339), to.Format(time.RFC3339))
body, err := io.ReadAll(req.Body)
require.NoError(t, err)
if !cmp.Equal(string(body), expectedBody) {

@ -10,8 +10,7 @@ var (
// instead of the default list of intervals
func SetAutoTimeGrain(intervalMs int64, timeGrains []int64) (string, error) {
autoInterval := FindClosestAllowedIntervalMS(intervalMs, timeGrains)
tg := &TimeGrain{}
autoTimeGrain, err := tg.createISO8601DurationFromIntervalMS(autoInterval)
autoTimeGrain, err := CreateISO8601DurationFromIntervalMS(autoInterval)
if err != nil {
return "", err
}

@ -12,13 +12,11 @@ import (
// TimeGrain handles conversions between
// the ISO 8601 Duration format (PT1H), Kbn units (1h) and Time Grains (1 hour)
// Also handles using the automatic Grafana interval to calculate a ISO 8601 Duration.
type TimeGrain struct{}
var (
smallTimeUnits = []string{"hour", "minute", "h", "m"}
)
func (tg *TimeGrain) createISO8601DurationFromIntervalMS(it int64) (string, error) {
func CreateISO8601DurationFromIntervalMS(it int64) (string, error) {
formatted := intervalv2.FormatDuration(time.Duration(it) * time.Millisecond)
if strings.Contains(formatted, "ms") {
@ -38,10 +36,10 @@ func (tg *TimeGrain) createISO8601DurationFromIntervalMS(it int64) (string, erro
return "PT1M", nil
}
return tg.createISO8601Duration(timeValue, unit), nil
return createISO8601Duration(timeValue, unit), nil
}
func (tg *TimeGrain) createISO8601Duration(timeValue int, timeUnit string) string {
func createISO8601Duration(timeValue int, timeUnit string) string {
for _, smallTimeUnit := range smallTimeUnits {
if timeUnit == smallTimeUnit {
return fmt.Sprintf("PT%v%v", timeValue, strings.ToUpper(timeUnit[0:1]))

@ -8,8 +8,6 @@ import (
)
func TestTimeGrain_createISO8601Duration(t *testing.T) {
tg := &TimeGrain{}
testCases := []struct {
name string
value int
@ -26,15 +24,13 @@ func TestTimeGrain_createISO8601Duration(t *testing.T) {
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
d := tg.createISO8601Duration(tc.value, tc.unit)
d := createISO8601Duration(tc.value, tc.unit)
assert.Equal(t, tc.expected, d)
})
}
}
func TestTimeGrain_createISO8601DurationFromIntervalMS(t *testing.T) {
tg := &TimeGrain{}
testCases := []struct {
name string
interval int64
@ -48,7 +44,7 @@ func TestTimeGrain_createISO8601DurationFromIntervalMS(t *testing.T) {
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
d, err := tg.createISO8601DurationFromIntervalMS(tc.interval)
d, err := CreateISO8601DurationFromIntervalMS(tc.interval)
require.NoError(t, err)
assert.Equal(t, tc.expected, d)
})

Loading…
Cancel
Save