Closed as not planned
Description
Go version
go version go1.22.2 darwin/arm64
Output of go env
in your module/workspace:
GO111MODULE=''
GOARCH='arm64'
GOBIN=''
GOCACHE='/Users/user/Library/Caches/go-build'
GOENV='/Users/user/Library/Application Support/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='arm64'
GOHOSTOS='darwin'
GOINSECURE=''
GOMODCACHE='/Users/user/go/pkg/mod'
GONOPROXY='*.sap.corp'
GONOSUMDB='*.sap.corp'
GOOS='darwin'
GOPATH='/Users/user/go'
GOPRIVATE='*.sap.corp'
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/local/go'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/local/go/pkg/tool/darwin_arm64'
GOVCS=''
GOVERSION='go1.22.2'
GCCGO='gccgo'
AR='ar'
CC='clang'
CXX='clang++'
CGO_ENABLED='1'
GOMOD='/Users/user/SAPDevelop/issues/MarshalJson/go.mod'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -ffile-prefix-map=/var/folders/lc/5666d_g13j92hx9n3jdh5g2w0000gn/T/go-build1386616878=/tmp/go-build -gno-record-gcc-switches -fno-common'
What did you do?
I'm working with Kubernetes and custom resources. For logging and log filtering, I added a MarshalJSON()
method to a struct field.
package main
import (
"encoding/json"
"fmt"
"time"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// Object1Meta wraps metav1.Object1Meta to control logging.
type Object1Meta struct {
metav1.ObjectMeta
}
type MyObjectSpec struct {
Value1 string
Value2 string
Secret string
}
type MyObjectStatus struct {
Status string
ErrMsg string
}
type MyObject1 struct {
metav1.TypeMeta `json:",inline"`
Object1Meta `json:"metadata,omitempty"`
Spec MyObjectSpec `json:"spec,omitempty"`
Status MyObjectStatus `json:"status,omitempty"`
}
// Object2Meta wraps metav1.Object1Meta to control logging like Object1Meta, but implements a MarshalJSON method.
type Object2Meta struct {
metav1.ObjectMeta
}
func (om Object2Meta) MarshalJSON() ([]byte, error) {
fields := make(map[string]interface{}, 4)
fields["name"] = om.Name
fields["namespace"] = om.Namespace
fields["generation"] = om.Generation
fields["creationTimestamp"] = &om.CreationTimestamp
return json.Marshal(fields)
}
type MyObject2 struct {
metav1.TypeMeta `json:",inline"`
Object2Meta `json:"metadata,omitempty"`
Spec MyObjectSpec `json:"spec,omitempty"`
Status MyObjectStatus `json:"status,omitempty"`
}
func main() {
now := metav1.NewTime(time.Now())
o1 := MyObject1{
TypeMeta: metav1.TypeMeta{
Kind: "object1", APIVersion: "api/v1",
},
Object1Meta: Object1Meta{metav1.ObjectMeta{
Name: "o1", Namespace: "ns1", Generation: 1234, CreationTimestamp: now,
}},
Spec: MyObjectSpec{
Value1: "value1", Value2: "value2", Secret: "hidden",
},
Status: MyObjectStatus{
Status: "ok",
},
}
b1, _ := json.Marshal(o1)
o2 := MyObject2{
TypeMeta: metav1.TypeMeta{
Kind: "object1", APIVersion: "api/v1",
},
Object2Meta: Object2Meta{metav1.ObjectMeta{
Name: "o1", Namespace: "ns1", Generation: 1234, CreationTimestamp: now,
}},
Spec: MyObjectSpec{
Value1: "value1", Value2: "value2", Secret: "hidden",
},
Status: MyObjectStatus{
Status: "ok",
},
}
b2, _ := json.Marshal(&o2)
fmt.Println("b1", string(b1))
fmt.Println("b2", string(b2))
}
Complete (vendored) source code: MarshalJson.zip
What did you see happen?
Calling json.Marshal()on
MyObject2` generates only the output from MarshalJSON(), all other entities from o2 are missing.
b1 {"kind":"object1","apiVersion":"api/v1","metadata":{"name":"o1","namespace":"ns1","generation":1234,"creationTimestamp":"2024-05-03T09:40:38Z"},"spec":{"Value1":"value1","Value2":"value2","Secret":"hidden"},"status":{"Status":"ok","ErrMsg":""}}
b2 {"creationTimestamp":"2024-05-03T09:40:38Z","generation":1234,"name":"o1","namespace":"ns1"}
What did you expect to see?
I expect the two structures in my sample program to generate the same JSON output.