@@ -80,7 +80,7 @@ func (b *Breadcrumb) MarshalJSON() ([]byte, error) {
8080
8181 if b .Timestamp .IsZero () {
8282 return json .Marshal (struct {
83- // Embed all of the fields of Breadcrumb.
83+ // Embed all the fields of Breadcrumb.
8484 * breadcrumb
8585 // Timestamp shadows the original Timestamp field and is meant to
8686 // remain nil, triggering the omitempty behavior.
@@ -723,45 +723,18 @@ type EventHint struct {
723723}
724724
725725type Log struct {
726- Timestamp time.Time `json:"timestamp,omitempty"`
727- TraceID TraceID `json:"trace_id,omitempty"`
726+ Timestamp time.Time `json:"timestamp"`
727+ TraceID TraceID `json:"trace_id"`
728+ SpanID SpanID `json:"span_id,omitempty"`
728729 Level LogLevel `json:"level"`
729730 Severity int `json:"severity_number,omitempty"`
730- Body string `json:"body,omitempty "`
731+ Body string `json:"body"`
731732 Attributes map [string ]Attribute `json:"attributes,omitempty"`
732733}
733734
734735// ToEnvelopeItem converts the Log to a Sentry envelope item for batching.
735736func (l * Log ) ToEnvelopeItem () (* protocol.EnvelopeItem , error ) {
736- type logJSON struct {
737- Timestamp * float64 `json:"timestamp,omitempty"`
738- TraceID string `json:"trace_id,omitempty"`
739- Level string `json:"level"`
740- Severity int `json:"severity_number,omitempty"`
741- Body string `json:"body,omitempty"`
742- Attributes map [string ]protocol.LogAttribute `json:"attributes,omitempty"`
743- }
744-
745- // Convert time.Time to seconds float if set
746- var ts * float64
747- if ! l .Timestamp .IsZero () {
748- sec := float64 (l .Timestamp .UnixNano ()) / 1e9
749- ts = & sec
750- }
751-
752- attrs := make (map [string ]protocol.LogAttribute , len (l .Attributes ))
753- for k , v := range l .Attributes {
754- attrs [k ] = protocol.LogAttribute {Value : v .Value , Type : string (v .Type )}
755- }
756-
757- logData , err := json .Marshal (logJSON {
758- Timestamp : ts ,
759- TraceID : l .TraceID .String (),
760- Level : string (l .Level ),
761- Severity : l .Severity ,
762- Body : l .Body ,
763- Attributes : attrs ,
764- })
737+ logData , err := json .Marshal (l )
765738 if err != nil {
766739 return nil , err
767740 }
@@ -808,3 +781,32 @@ type Attribute struct {
808781 Value any `json:"value"`
809782 Type AttrType `json:"type"`
810783}
784+
785+ // MarshalJSON is a custom implementation that skips SpanID and timestamp when empty.
786+ func (l * Log ) MarshalJSON () ([]byte , error ) {
787+ type log Log
788+
789+ var spanID string
790+ if l .SpanID != zeroSpanID {
791+ spanID = l .SpanID .String ()
792+ }
793+
794+ var ts json.RawMessage
795+ if ! l .Timestamp .IsZero () {
796+ b , err := l .Timestamp .MarshalJSON ()
797+ if err != nil {
798+ return nil , err
799+ }
800+ ts = b
801+ }
802+
803+ return json .Marshal (struct {
804+ * log
805+ SpanID string `json:"span_id,omitempty"`
806+ Timestamp json.RawMessage `json:"timestamp,omitempty"`
807+ }{
808+ log : (* log )(l ),
809+ SpanID : spanID ,
810+ Timestamp : ts ,
811+ })
812+ }
0 commit comments