func TranslateLogEntry()

in receiver/googlecloudpubsubreceiver/internal/log_entry.go [114:262]


func TranslateLogEntry(data []byte) (pcommon.Resource, plog.LogRecord, error) {
	lr := plog.NewLogRecord()
	res := pcommon.NewResource()

	var src map[string]stdjson.RawMessage
	err := json.Unmarshal(data, &src)
	if err != nil {
		return res, lr, err
	}

	resAttrs := res.Attributes()
	attrs := lr.Attributes()

	for k, v := range src {
		// Pick out some keys for special handling, and let the rest
		// pass through to be translated according to the schema.
		switch k {
		// Unpack as suggested in the logs data model appendix
		//   https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/data-model-appendix.md#google-cloud-logging
		case "insertId":
			// timestamp -> Attributes[“log.record.uid”]
			// see: https://github.com/open-telemetry/semantic-conventions/blob/main/model/logs/general.yaml
			var insertID string
			err = json.Unmarshal(v, &insertID)
			if err != nil {
				return res, lr, err
			}
			attrs.PutStr("log.record.uid", insertID)
			delete(src, k)
		case "timestamp":
			// timestamp -> Timestamp
			var t time.Time
			err = json.Unmarshal(v, &t)
			if err != nil {
				return res, lr, err
			}
			lr.SetTimestamp(pcommon.NewTimestampFromTime(t))
			delete(src, k)
		case "receiveTimestamp":
			// timestamp -> Timestamp
			var t time.Time
			err = json.Unmarshal(v, &t)
			if err != nil {
				return res, lr, err
			}
			lr.SetObservedTimestamp(pcommon.NewTimestampFromTime(t))
			delete(src, k)
		case "resource":
			// resource -> Resource
			// mapping type -> gcp.resource_type
			// labels -> gcp.<label>
			var protoRes monitoredres.MonitoredResource
			err = protojson.Unmarshal(v, &protoRes)
			if err != nil {
				return res, lr, err
			}

			resAttrs.EnsureCapacity(len(protoRes.GetLabels()) + 1)
			resAttrs.PutStr("gcp.resource_type", protoRes.GetType())
			for k, v := range protoRes.GetLabels() {
				resAttrs.PutStr(strcase.ToSnakeWithIgnore(fmt.Sprintf("gcp.%v", k), "."), v)
			}
			delete(src, k)
		case "logName":
			var logName string
			err = json.Unmarshal(v, &logName)
			if err != nil {
				return res, lr, err
			}
			// log_name -> Attributes[“gcp.log_name”]
			attrs.PutStr("gcp.log_name", logName)
			delete(src, k)
		case "jsonPayload", "textPayload":
			// {json,proto,text}_payload -> Body
			var payload any
			err = json.Unmarshal(v, &payload)
			if err != nil {
				return res, lr, err
			}
			// Note: json.Unmarshal will turn a bare string into a
			// go string, so this call will correctly set the body
			// to a string Value.
			_ = lr.Body().FromRaw(payload)
			delete(src, k)
		case "protoPayload":
			// {json,proto,text}_payload -> Body
			err = translateInto(lr.Body().SetEmptyMap(), (&anypb.Any{}).ProtoReflect().Descriptor(), v)
			if err != nil {
				return res, lr, err
			}
			delete(src, k)
		case "severity":
			var severity string
			err = json.Unmarshal(v, &severity)
			if err != nil {
				return res, lr, err
			}
			// severity -> Severity
			// According to the spec, this is the original string representation of
			// the severity as it is known at the source:
			//   https://opentelemetry.io/docs/reference/specification/logs/data-model/#field-severitytext
			lr.SetSeverityText(severity)
			lr.SetSeverityNumber(cloudLoggingSeverityToNumber(severity))
			delete(src, k)
		case "trace":
			var trace string
			err = json.Unmarshal(v, &trace)
			if err != nil {
				return res, lr, err
			}
			lr.SetTraceID(cloudLoggingTraceToTraceIDBytes(trace))
			delete(src, k)
		case "spanId":
			var spanID string
			err = json.Unmarshal(v, &spanID)
			if err != nil {
				return res, lr, err
			}
			lr.SetSpanID(spanIDStrToSpanIDBytes(spanID))
			delete(src, k)
		case "labels":
			var labels map[string]string
			err = json.Unmarshal(v, &labels)
			if err != nil {
				return res, lr, err
			}
			// labels -> Attributes
			for k, v := range labels {
				attrs.PutStr(k, v)
			}
			delete(src, k)
		case "httpRequest":
			httpRequestAttrs := attrs.PutEmptyMap("gcp.http_request")
			err = translateInto(httpRequestAttrs, getLogEntryDescriptor().Fields().ByJSONName(k).Message(), v, snakeifyKeys)
			if err != nil {
				return res, lr, err
			}
			delete(src, k)
		default:
		}
	}

	// All other fields -> Attributes["gcp.*"]
	// At this point we cleared all the fields that have special handling;
	// translate the rest into the attributes map.
	_ = translateInto(attrs, getLogEntryDescriptor(), src, preserveDst, prefixKeys("gcp."), snakeifyKeys)

	return res, lr, nil
}