Cloudwatch: Change type of ts field in log responses to time (#66525)

* make timestamp field time type

* Add test for type on handleLogEvents data frame field response

---------

Co-authored-by: Shirley Leu <4163034+fridgepoet@users.noreply.github.com>
This commit is contained in:
Sven Grossmann
2023-04-14 16:21:16 +02:00
committed by GitHub
parent e65163ba4e
commit 8567ec92b0
3 changed files with 74 additions and 3 deletions

View File

@@ -8,6 +8,7 @@ import (
"math"
"sort"
"strings"
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
@@ -164,7 +165,7 @@ func (e *cloudWatchExecutor) handleGetLogEvents(ctx context.Context, logsClient
}
messages := make([]*string, 0)
timestamps := make([]*int64, 0)
timestamps := make([]time.Time, 0)
sort.Slice(logEvents.Events, func(i, j int) bool {
return *(logEvents.Events[i].Timestamp) > *(logEvents.Events[j].Timestamp)
@@ -172,7 +173,7 @@ func (e *cloudWatchExecutor) handleGetLogEvents(ctx context.Context, logsClient
for _, event := range logEvents.Events {
messages = append(messages, event.Message)
timestamps = append(timestamps, event.Timestamp)
timestamps = append(timestamps, time.UnixMilli(*event.Timestamp).UTC())
}
timestampField := data.NewField("ts", nil, timestamps)

View File

@@ -15,13 +15,16 @@ import (
"github.com/grafana/grafana-plugin-sdk-go/backend/instancemgmt"
"github.com/grafana/grafana-plugin-sdk-go/data"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/mocks"
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/models"
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/utils"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestQuery_GetLogEvents(t *testing.T) {
func TestQuery_handleGetLogEvents_passes_nil_start_and_end_times_to_GetLogEvents(t *testing.T) {
origNewCWLogsClient := NewCWLogsClient
t.Cleanup(func() {
NewCWLogsClient = origNewCWLogsClient
@@ -107,6 +110,58 @@ func TestQuery_GetLogEvents(t *testing.T) {
}
}
func TestQuery_GetLogEvents_returns_response_from_GetLogEvents_to_data_frame_field(t *testing.T) {
origNewCWLogsClient := NewCWLogsClient
t.Cleanup(func() {
NewCWLogsClient = origNewCWLogsClient
})
var cli *mocks.MockLogEvents
NewCWLogsClient = func(sess *session.Session) cloudwatchlogsiface.CloudWatchLogsAPI {
return cli
}
im := datasource.NewInstanceManager(func(s backend.DataSourceInstanceSettings) (instancemgmt.Instance, error) {
return DataSource{Settings: models.CloudWatchSettings{}}, nil
})
executor := newExecutor(im, newTestConfig(), &fakeSessionCache{}, featuremgmt.WithFeatures())
cli = &mocks.MockLogEvents{}
cli.On("GetLogEventsWithContext", mock.Anything, mock.Anything, mock.Anything).Return(&cloudwatchlogs.GetLogEventsOutput{
Events: []*cloudwatchlogs.OutputLogEvent{{
Message: utils.Pointer("some message"),
Timestamp: utils.Pointer(int64(15)),
}}}, nil)
resp, err := executor.QueryData(context.Background(), &backend.QueryDataRequest{
PluginContext: backend.PluginContext{
DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{},
},
Queries: []backend.DataQuery{
{
RefID: "A",
TimeRange: backend.TimeRange{From: time.Unix(0, 0), To: time.Unix(1, 0)},
JSON: json.RawMessage(`{
"type": "logAction",
"subtype": "GetLogEvents",
"logGroupName": "foo",
"logStreamName": "bar",
"endTime": 1,
"startFromHead": false
}`),
},
},
})
require.NoError(t, err)
respA, ok := resp.Responses["A"]
assert.True(t, ok)
expectedTsField := data.NewField("ts", nil, []time.Time{time.UnixMilli(15).UTC()})
expectedMessageField := data.NewField("line", nil, []*string{utils.Pointer("some message")})
expectedTsField.SetConfig(&data.FieldConfig{DisplayName: "Time"})
assert.Equal(t, []*data.Field{expectedTsField, expectedMessageField}, respA.Frames[0].Fields)
}
func TestQuery_StartQuery(t *testing.T) {
origNewCWLogsClient := NewCWLogsClient
t.Cleanup(func() {

View File

@@ -1,7 +1,10 @@
package mocks
import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/service/cloudwatchlogs"
"github.com/aws/aws-sdk-go/service/cloudwatchlogs/cloudwatchlogsiface"
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/models/resources"
"github.com/stretchr/testify/mock"
)
@@ -47,3 +50,15 @@ func (f *MockFeatures) IsEnabled(feature string) bool {
return args.Bool(0)
}
type MockLogEvents struct {
cloudwatchlogsiface.CloudWatchLogsAPI
mock.Mock
}
func (m *MockLogEvents) GetLogEventsWithContext(ctx aws.Context, input *cloudwatchlogs.GetLogEventsInput, option ...request.Option) (*cloudwatchlogs.GetLogEventsOutput, error) {
args := m.Called(ctx, input, option)
return args.Get(0).(*cloudwatchlogs.GetLogEventsOutput), args.Error(1)
}