| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162 |
- package tracing
- import (
- "bytes"
- "github.com/coroot/coroot-node-agent/ebpftracer"
- "go.opentelemetry.io/otel/attribute"
- "go.opentelemetry.io/otel/codes"
- semconv "go.opentelemetry.io/otel/semconv/v1.18.0"
- "go.opentelemetry.io/otel/trace"
- "strings"
- "time"
- )
- const (
- MemcacheDBItemKeyName attribute.Key = "db.memcached.item"
- )
- func handleMemcachedQuery(start, end time.Time, r *ebpftracer.L7Request, attrs []attribute.KeyValue) {
- cmd, items := parseMemcached(r.Payload[:])
- if cmd == "" {
- return
- }
- _, span := tracer.Start(nil, cmd, trace.WithTimestamp(start), trace.WithSpanKind(trace.SpanKindClient))
- if len(items) == 1 {
- attrs = append(attrs, MemcacheDBItemKeyName.String(items[0]))
- } else if len(items) > 1 {
- attrs = append(attrs, MemcacheDBItemKeyName.StringSlice(items))
- }
- span.SetAttributes(append(attrs, semconv.DBSystemMemcached, semconv.DBOperation(cmd))...)
- if r.Status == 500 {
- span.SetStatus(codes.Error, "")
- }
- span.End(trace.WithTimestamp(end))
- }
- func parseMemcached(payload []byte) (string, []string) {
- cmd, rest, ok := bytes.Cut(payload, space)
- if !ok {
- return "", nil
- }
- command := string(cmd)
- switch command {
- case "set", "add", "cas", "append", "prepend", "replace", "delete", "incr", "decr", "touch":
- if key, _, ok := bytes.Cut(rest, space); ok {
- return command, []string{string(key)}
- }
- case "gat", "gats":
- _, rest, ok = bytes.Cut(rest, space)
- if ok {
- keys, _, ok := bytes.Cut(rest, crlf)
- if ok {
- return command, strings.Split(string(keys), " ")
- }
- }
- case "get", "gets":
- keys, _, ok := bytes.Cut(rest, crlf)
- if ok {
- return command, strings.Split(string(keys), " ")
- }
- }
- return "", nil
- }
|