mirror of
https://github.com/hanzoai/otel-collector.git
synced 2026-10-30 18:26:25 +00:00
## Pull Request ### Summary Replaces matching on `even.Name == "exception"` with an `is_exception(event.Name)` function which classifies `"exception"` or anything ending in `".exception"` as one. ### Related Issues <!-- Reference any related issues (e.g. Fixes #123, Closes #456) --> Closes #790 ### Resource Impact **Will this change affect the application's resource usage?** - [ ] Yes - [x] No ### tested? Tested with a local build of Signoz. I did have to update the `bytedance/sonic` dependency to `1.15.0` in order to get it to build (on Windows). I did not include those changes to keep this MR focused but I thought I should mention it.
102 lines
3.4 KiB
Go
102 lines
3.4 KiB
Go
package traces
|
|
|
|
import (
|
|
"crypto/md5"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/goccy/go-json"
|
|
|
|
"github.com/google/uuid"
|
|
"go.opentelemetry.io/collector/pdata/pcommon"
|
|
"go.opentelemetry.io/collector/pdata/ptrace"
|
|
"go.uber.org/zap/zapcore"
|
|
)
|
|
|
|
// IsExceptionEvent reports whether the given span event name represents an
|
|
// exception event per the OpenTelemetry semantic conventions.
|
|
//
|
|
// Recognized event names:
|
|
//
|
|
// - "exception" (stable)
|
|
// https://opentelemetry.io/docs/specs/semconv/exceptions/exceptions-spans/
|
|
//
|
|
// - "http.client.request.exception", "http.server.request.exception" (development)
|
|
// https://opentelemetry.io/docs/specs/semconv/http/http-exceptions/
|
|
//
|
|
// - "db.client.operation.exception" (development)
|
|
// https://opentelemetry.io/docs/specs/semconv/db/database-exceptions/
|
|
//
|
|
// - "rpc.client.call.exception", "rpc.server.call.exception" (development)
|
|
// https://opentelemetry.io/docs/specs/semconv/rpc/rpc-exceptions/
|
|
//
|
|
// The OTel semconv naming pattern for domain-specific exception events follows
|
|
// the pattern: "{domain}.{component}.{operation}.exception",
|
|
// we match on the suffix ".exception" to be forward compatible with new conventions.
|
|
func IsExceptionEvent(eventName string) bool {
|
|
return eventName == "exception" || strings.HasSuffix(eventName, ".exception")
|
|
}
|
|
|
|
// This has been copied from the exporter. The exporter needs to read from here.
|
|
type Event struct {
|
|
Name string `json:"name,omitempty"`
|
|
TimeUnixNano uint64 `json:"timeUnixNano,omitempty"`
|
|
AttributeMap map[string]string `json:"attributeMap,omitempty"`
|
|
IsError bool `json:"isError,omitempty"`
|
|
}
|
|
|
|
func (e *Event) MarshalLogObject(enc zapcore.ObjectEncoder) error {
|
|
enc.AddString("name", e.Name)
|
|
enc.AddUint64("timeUnixNano", e.TimeUnixNano)
|
|
enc.AddBool("isError", e.IsError)
|
|
enc.AddString("attributeMap", fmt.Sprintf("%v", e.AttributeMap))
|
|
return nil
|
|
}
|
|
|
|
// This has been copied from the exporter. The exporter needs to read from here.
|
|
type ErrorEvent struct {
|
|
Event Event `json:"errorEvent,omitempty"`
|
|
ErrorID string `json:"errorID,omitempty"`
|
|
ErrorGroupID string `json:"errorGroupID,omitempty"`
|
|
}
|
|
|
|
func NewEventsAndErrorEvents(input ptrace.SpanEventSlice, serviceName string, lowCardinalExceptionGrouping bool) ([]string, []ErrorEvent) {
|
|
events := make([]string, 0)
|
|
errorEvents := make([]ErrorEvent, 0)
|
|
|
|
for i := 0; i < input.Len(); i++ {
|
|
event := Event{
|
|
Name: input.At(i).Name(),
|
|
TimeUnixNano: uint64(input.At(i).Timestamp()),
|
|
AttributeMap: map[string]string{},
|
|
IsError: false,
|
|
}
|
|
|
|
input.At(i).Attributes().Range(func(k string, v pcommon.Value) bool {
|
|
event.AttributeMap[k] = v.AsString()
|
|
return true
|
|
})
|
|
errorEvent := ErrorEvent{}
|
|
if IsExceptionEvent(event.Name) {
|
|
event.IsError = true
|
|
errorEvent.Event = event
|
|
uuidWithHyphen := uuid.New()
|
|
uuid := strings.Replace(uuidWithHyphen.String(), "-", "", -1)
|
|
errorEvent.ErrorID = uuid
|
|
var hash [16]byte
|
|
if lowCardinalExceptionGrouping {
|
|
hash = md5.Sum([]byte(serviceName + errorEvent.Event.AttributeMap["exception.type"]))
|
|
} else {
|
|
hash = md5.Sum([]byte(serviceName + errorEvent.Event.AttributeMap["exception.type"] + errorEvent.Event.AttributeMap["exception.message"]))
|
|
}
|
|
errorEvent.ErrorGroupID = fmt.Sprintf("%x", hash)
|
|
}
|
|
|
|
stringEvent, _ := json.Marshal(event)
|
|
events = append(events, string(stringEvent))
|
|
errorEvents = append(errorEvents, errorEvent)
|
|
}
|
|
|
|
return events, errorEvents
|
|
}
|