Skip to content

Commit

Permalink
Log list or map (#535)
Browse files Browse the repository at this point in the history
* Use Is*Type() functions

* test for creating log fields for form body, cookies or headers

* fix: allow `cty.ListVal` and `cty.MapVal` in convert function used for custom logs

* changelog entry
  • Loading branch information
johakoch authored Jul 8, 2022
1 parent bf733fe commit bbfa07d
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 16 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

Unreleased changes are available as `avenga/couper:edge` container.

* **Fixed**
* [`form_body`, `headers` and `cookies`](./docs/REFERENCE.md#request) can now be properly [custom-logged](./docs/LOGS.md#custom-logging) ([#535](https://github.com/avenga/couper/pull/535))

---

## [1.9.2](https://github.com/avenga/couper/releases/tag/v1.9.2)
Expand Down
32 changes: 16 additions & 16 deletions internal/seetie/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func ValueToMap(val cty.Value) map[string]interface{} {
return result
}
var valMap map[string]cty.Value
if isTuple(val) {
if isListOrTuple(val) {
valMap = val.AsValueSlice()[0].AsValueMap()
} else {
valMap = val.AsValueMap()
Expand All @@ -45,7 +45,7 @@ func ValueToMap(val cty.Value) map[string]interface{} {
case cty.Map(cty.NilType):
result[k] = nil
default:
if isTuple(v) {
if isListOrTuple(v) {
result[k] = ValueToStringSlice(v)
continue
}
Expand Down Expand Up @@ -276,8 +276,8 @@ func ValueToLogFields(val cty.Value) logrus.Fields {
fields := logrus.Fields{}

for k, v := range val.AsValueMap() {
if isTuple(v) {
fields[k] = ValueToLogFieldsFromTuple(v)
if isListOrTuple(v) {
fields[k] = valueToLogFieldsFromListOrTuple(v)
} else {
switch v.Type() {
case cty.Bool:
Expand All @@ -288,7 +288,7 @@ func ValueToLogFields(val cty.Value) logrus.Fields {
f, _ := v.AsBigFloat().Float64()
fields[k] = f
default:
if isObject(v) {
if isMapOrObject(v) {
fields[k] = ValueToLogFields(v)
}
}
Expand All @@ -298,15 +298,15 @@ func ValueToLogFields(val cty.Value) logrus.Fields {
return fields
}

func ValueToLogFieldsFromTuple(val cty.Value) []interface{} {
if !isTuple(val) {
func valueToLogFieldsFromListOrTuple(val cty.Value) []interface{} {
if !isListOrTuple(val) {
return nil
}

var values []interface{}
for _, v := range val.AsValueSlice() {
if isTuple(v) {
values = append(values, ValueToLogFieldsFromTuple(v))
if isListOrTuple(v) {
values = append(values, valueToLogFieldsFromListOrTuple(v))
} else {
switch v.Type() {
case cty.Bool:
Expand All @@ -317,7 +317,7 @@ func ValueToLogFieldsFromTuple(val cty.Value) []interface{} {
f, _ := v.AsBigFloat().Float64()
values = append(values, f)
default:
if isObject(v) {
if isMapOrObject(v) {
values = append(values, ValueToLogFields(v))
}
}
Expand Down Expand Up @@ -359,18 +359,18 @@ func ToString(s interface{}) string {
}
}

// isObject checks by type name since object is not comparable by type.
func isObject(v cty.Value) bool {
func isMapOrObject(v cty.Value) bool {
if v.IsNull() {
return false
}
return v.Type().FriendlyNameForConstraint() == "object"
t := v.Type()
return t.IsMapType() || t.IsObjectType()
}

// isTuple checks by type name since tuple is not comparable by type.
func isTuple(v cty.Value) bool {
func isListOrTuple(v cty.Value) bool {
if v.IsNull() {
return false
}
return v.Type().FriendlyNameForConstraint() == "tuple"
t := v.Type()
return t.IsListType() || t.IsTupleType()
}
36 changes: 36 additions & 0 deletions internal/seetie/convert_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@ package seetie

import (
"fmt"
"net/http"
"testing"

"github.com/google/go-cmp/cmp"
"github.com/sirupsen/logrus"
"github.com/zclconf/go-cty/cty"
)

Expand Down Expand Up @@ -37,3 +40,36 @@ func Test_stringListToValue(t *testing.T) {
})
}
}

func Test_ValueToLogFields(t *testing.T) {
type testCase struct {
name string
val cty.Value
expLog logrus.Fields
}
for _, tc := range []testCase{
{
name: "form body",
val: ValuesMapToValue(map[string][]string{"a": []string{"b"}}),
expLog: logrus.Fields{"v": logrus.Fields{"a": []interface{}{"b"}}},
},
{
name: "cookies",
val: CookiesToMapValue([]*http.Cookie{&http.Cookie{Name: "c", Value: "d"}}),
expLog: logrus.Fields{"v": logrus.Fields{"c": "d"}},
},
{
name: "headers",
val: HeaderToMapValue(http.Header{"c": []string{"d"}}),
expLog: logrus.Fields{"v": logrus.Fields{"c": "d"}},
},
} {
t.Run(tc.name, func(subT *testing.T) {
logs := cty.MapVal(map[string]cty.Value{"v": tc.val})
lf := ValueToLogFields(logs)
if !cmp.Equal(tc.expLog, lf) {
t.Errorf("Expected\n%#v, got:\n%#v", tc.expLog, lf)
}
})
}
}

0 comments on commit bbfa07d

Please sign in to comment.