如何将 Google Cloud Pub/Sub 的负载转换为 Golang 中的 LogEntry 对象

huangapple go评论76阅读模式
英文:

How to convert google cloud pubsub payload to LogEntry object in Golang

问题

我创建了一个Logs Router Sink来将日志导出到Pub/Sub。我的Golang应用程序应该使用Google客户端库(Golang)通过专用订阅来消费Pub/Sub中的消息。

订阅接收到的消息是LogEntry对象的JSON表示。

问题是:
如何将JSON解组为有用的Golang对象?

  • 我的第一次尝试是将JSON解组为Entry对象。但是这个尝试失败了,因为该对象的字段没有与JSON字段的映射,特别是textPayload字段没有被解组。
  • 第二次尝试是将JSON解组为LogEntry对象。这个对象似乎符合定义,但它的主要目的是protobufs(而不是JSON)。特别是当我尝试将LogEntry的JSON解组到它时,我得到了以下错误:

> 无法将字符串解组为类型为ltype.LogSeverity的Go结构体字段LogEntry.severity

英文:

I created a Logs Router Sink to export logs to a Pub/Sub.
My Golang application is supposed to consume messages from this Pub/Sub via a dedicated Subscription using google client library (Golang).

The messages received on the Subscription are JSON representations of LogEntry objects.

The question:
How to unmarshal the JSONs into useful Golang objects?

  • my first attempt was to unmarshal the JSONs to Entry object. The attempt failed because this object has no JSON mappings for the fields, in particular textPayload JSON field was not unmarshalled
  • the second attempt was to unmarshal the JSONs to LogEntry object. This object seems to fit the definition, but its main purpose is protobufs (and not JSON). In particular when I tried to unmarshal a LogEntry JSON into it, I got the following error

> cannot unmarshal string into Go struct field LogEntry.severity of type ltype.LogSeverity

答案1

得分: 1

如果你遇到关于protoPayload或者timestamppb.Timestamp的错误,那可能是一个协议缓冲区的JSON表示。在Go语言中,你应该使用protojson包来编组/解组协议缓冲区。以下是一个示例:

import (
	... 省略 ...

	_ "google.golang.org/genproto/googleapis/cloud/audit"
	logging "google.golang.org/genproto/googleapis/logging/v2"
	"google.golang.org/protobuf/encoding/protojson"
)

func handlerLogEntry(w http.ResponseWriter, r *http.Request) {
	var le logging.LogEntry
	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		http.Error(w, "Bad HTTP Request", http.StatusBadRequest)
		log.Printf("handlerLogEntry ReadAll error: %v", err)
		return
	}
	if err := protojson.Unmarshal(body, &le); err != nil {
		http.Error(w, "Bad HTTP Request", http.StatusBadRequest)
		log.Printf("handlerLogEntry Unmarshal error: %v", err)
		return
	}
	s := fmt.Sprintf("handlerLogEntry: %#v", le)
	log.Printf(s)
	fmt.Fprintln(w, s)
}

希望对你有帮助!

英文:

If you get errors about protoPayload or timestamppb.Timestamp it probably is a JSON representation of a protocol buffer. To Marshall/Unmarshal protocol buffers in Go you should use the protojson package. Example:

import (
	... omitted ...

	_ "google.golang.org/genproto/googleapis/cloud/audit"
	logging "google.golang.org/genproto/googleapis/logging/v2"
	"google.golang.org/protobuf/encoding/protojson"
)

func handlerLogEntry(w http.ResponseWriter, r *http.Request) {
	var le logging.LogEntry
	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		http.Error(w, "Bad HTTP Request", http.StatusBadRequest)
		log.Printf("handlerLogEntry ReadAll error: %", err)
		return
	}
	if err := protojson.Unmarshal(body, &le); err != nil {
		http.Error(w, "Bad HTTP Request", http.StatusBadRequest)
		log.Printf("handlerLogEntry Unmarshal error: %", err)
		return
	}
	s := fmt.Sprintf("handlerLogEntry: %#v", le)
	log.Printf(s)
	fmt.Fprintln(w, s)
}

答案2

得分: 0

你正在尝试解析的JSON包含字符串而不是整数。日志严重程度代码应该是以下之一:

type LogSeverity int32

const (
    // (0) The log entry has no assigned severity level.
    LogSeverity_DEFAULT LogSeverity = 0
    // (100) Debug or trace information.
    LogSeverity_DEBUG LogSeverity = 100
    // (200) Routine information, such as ongoing status or performance.
    LogSeverity_INFO LogSeverity = 200
    // (300) Normal but significant events, such as start up, shut down, or
    // a configuration change.
    LogSeverity_NOTICE LogSeverity = 300
    // (400) Warning events might cause problems.
    LogSeverity_WARNING LogSeverity = 400
    // (500) Error events are likely to cause problems.
    LogSeverity_ERROR LogSeverity = 500
    // (600) Critical events cause more severe problems or outages.
    LogSeverity_CRITICAL LogSeverity = 600
    // (700) A person must take an action immediately.
    LogSeverity_ALERT LogSeverity = 700
    // (800) One or more systems are unusable.
    LogSeverity_EMERGENCY LogSeverity = 800
)

请确保在路由器接收器中设置了正确的JSON。

英文:

JSON you are trying to parse contains string instead of an integer.
The Log severity code should be one of these:

 type LogSeverity int32

const (
	// (0) The log entry has no assigned severity level.
	LogSeverity_DEFAULT LogSeverity = 0
	// (100) Debug or trace information.
	LogSeverity_DEBUG LogSeverity = 100
	// (200) Routine information, such as ongoing status or performance.
	LogSeverity_INFO LogSeverity = 200
	// (300) Normal but significant events, such as start up, shut down, or
	// a configuration change.
	LogSeverity_NOTICE LogSeverity = 300
	// (400) Warning events might cause problems.
	LogSeverity_WARNING LogSeverity = 400
	// (500) Error events are likely to cause problems.
	LogSeverity_ERROR LogSeverity = 500
	// (600) Critical events cause more severe problems or outages.
	LogSeverity_CRITICAL LogSeverity = 600
	// (700) A person must take an action immediately.
	LogSeverity_ALERT LogSeverity = 700
	// (800) One or more systems are unusable.
	LogSeverity_EMERGENCY LogSeverity = 800
)

Make sure you are setting the correct JSON in Router Sink.

huangapple
  • 本文由 发表于 2021年8月2日 22:20:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/68623215.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定