return os.Stdout(p)
здесь не имеет смысла, но в любом случае основная проблема заключается в том, что если на входе json и вы его декодировали, вы не знаете, что это за исходный ввод. Нет простого способа найти строку для удаления, так как то, что у вас уже декодировано.
Конечно, вы можете написать свой собственный json парсер и найти и удалите предмет таким образом. Это единственный способ сохранить остаток кодировки как есть.
Более простой вариант - удалить ошибку и перекодировать. Достаточно того, что вы не показали здесь, что трудно понять, будет ли это нормально, но я взял ваш пример процедуры, сделал ее компилируемой и построил для нее небольшую тестовую среду, но вот она (и ссылка на Go площадка ):
package main
import (
"encoding/json"
"fmt"
"os"
)
type loggedEvent struct {
Thing1 string `json:"thing1"`
ErrWithStackTrace *string `json:"err,omitempty"`
Thing2 string `json:"thing2"`
}
var inputs [][]byte = [][]byte{
[]byte(`{"thing1":"a string","err":"here is a stack trace","thing2":"another string"}`),
[]byte(`{"thing1":"a\u0020string","err":"here\u0020is\u0020a\u0020stack\u0020trace","thing2":"u-encoded"}`),
[]byte(`{"thing1":"more strings","thing2":"no error this time"}`),
}
type customWriter struct{}
func (w *customWriter) Write(p []byte) (int, error) {
e := loggedEvent{}
if err := json.Unmarshal(p, &e); err != nil {
fmt.Printf("note: unable to unmarshal %q\n", p)
return len(p), nil
}
if e.ErrWithStackTrace != nil {
// fmt.Printf("note: removing ErrWithStackTrace part\n")
e.ErrWithStackTrace = nil
}
s, err := json.Marshal(e)
if err != nil {
fmt.Printf("help, failed to re-marshal e=%v: err=%v\n", e, err)
return 0, err
}
s = append(s, '\n')
return os.Stdout.Write(s)
}
func main() {
w := &customWriter{}
for _, inp := range inputs {
ret, err := w.Write(inp)
if err != nil {
fmt.Printf("ret = %d, err = %v\n", ret, err)
}
}
}