diff --git a/pkg/pb/synthetic_monitoring/checks_extra.go b/pkg/pb/synthetic_monitoring/checks_extra.go index 11e20d71b..4f1d8d544 100644 --- a/pkg/pb/synthetic_monitoring/checks_extra.go +++ b/pkg/pb/synthetic_monitoring/checks_extra.go @@ -20,6 +20,7 @@ package synthetic_monitoring //go:generate ../../../scripts/enumer -type=MultiHttpEntryAssertionType,MultiHttpEntryAssertionSubjectVariant,MultiHttpEntryAssertionConditionVariant,MultiHttpEntryVariableType -trimprefix=MultiHttpEntryAssertionType_,MultiHttpEntryAssertionSubjectVariant_,MultiHttpEntryAssertionConditionVariant_,MultiHttpEntryVariableType_ -transform=upper -output=multihttp_string.go import ( + "encoding/json" "errors" "fmt" "mime" @@ -30,6 +31,7 @@ import ( "strings" "time" + "github.com/rs/zerolog" "golang.org/x/exp/constraints" "golang.org/x/net/http/httpguts" ) @@ -1585,3 +1587,19 @@ func GetCheckInstance(checkType CheckType) Check { return instance } + +func (ri RemoteInfo) MarshalZerologObject(e *zerolog.Event) { + e.Str("name", ri.Name). + Str("url", ri.Url). + Str("username", ri.Username). + Str("password", "") +} + +func (ri RemoteInfo) MarshalJSON() ([]byte, error) { + type T RemoteInfo + var tmp T = T(ri) + + tmp.Password = `` + + return json.Marshal(tmp) +} diff --git a/pkg/pb/synthetic_monitoring/checks_extra_test.go b/pkg/pb/synthetic_monitoring/checks_extra_test.go index 00863b6d6..fc8353ad2 100644 --- a/pkg/pb/synthetic_monitoring/checks_extra_test.go +++ b/pkg/pb/synthetic_monitoring/checks_extra_test.go @@ -1,12 +1,15 @@ package synthetic_monitoring import ( + "bytes" "encoding/json" "errors" "flag" + "reflect" "strings" "testing" + "github.com/rs/zerolog" "github.com/stretchr/testify/require" ) @@ -1973,3 +1976,72 @@ func TestGetCheckInstance(t *testing.T) { require.NoError(t, check.Validate()) } } + +func requireRemoteInfoFields(t *testing.T) { + t.Helper() + + // The expected fields in the RemoteInfo struct. It's necessary to + // assert this list so that if the implementation ever changes, we can + // go update the MarshalZerologObject method accordingly. + expectedFields := []string{ + "Name", + "Url", + "Username", + "Password", + } + + remoteInfoType := reflect.TypeOf(RemoteInfo{}) + actualFields := make([]string, 0, remoteInfoType.NumField()) + + for i := range remoteInfoType.NumField() { + field := remoteInfoType.Field(i) + if field.IsExported() { + actualFields = append(actualFields, field.Name) + } + } + + require.ElementsMatch(t, expectedFields, actualFields, + "RemoteInfo struct fields have changed. Update the expected fields list and review any code that depends on the field order.") +} + +func TestRemoteInfoMarshalZerologObject(t *testing.T) { + requireRemoteInfoFields(t) + + remoteInfo := RemoteInfo{ + Name: "the name", + Url: "https://example.com", + Username: "the username", + Password: "the password", + } + + var buf bytes.Buffer + logger := zerolog.New(&buf) + + logger.Info().Interface("remote_info", remoteInfo).Send() + + // Note that the order of the expected fields is fixed. If the + // implementation changes, this test will break. + expected := `{"level":"info","remote_info":{"name":"the name","url":"https://example.com","username":"the username","password":""}}` + "\n" + actual := buf.String() + + require.Equal(t, expected, actual) +} + +func TestRemoteInfoMarshalJSON(t *testing.T) { + requireRemoteInfoFields(t) + + remoteInfo := RemoteInfo{ + Name: "the name", + Url: "https://example.com", + Username: "the username", + Password: "the password", + } + + var buf bytes.Buffer + err := json.NewEncoder(&buf).Encode(&remoteInfo) + require.NoError(t, err) + + expected := `{"name":"the name","url":"https://example.com","username":"the username","password":"\u003cencrypted\u003e"}` + actual := strings.TrimSpace(buf.String()) + require.Equal(t, expected, actual, "JSON encoding of RemoteInfo did not match expected output") +}