Example #1
0
        internal static Proto.Trace.V1.Span ToProtoSpan(this Trace.Span otelSpan)
        {
            try
            {
                // protobuf doesn't understand Span<T> yet: https://github.com/protocolbuffers/protobuf/issues/3431
                Span <byte> traceIdBytes = stackalloc byte[16];
                Span <byte> spanIdBytes  = stackalloc byte[8];

                otelSpan.Context.TraceId.CopyTo(traceIdBytes);
                otelSpan.Context.SpanId.CopyTo(spanIdBytes);

                var parentSpanIdString = ByteString.Empty;
                if (otelSpan.ParentSpanId != default)
                {
                    Span <byte> parentSpanIdBytes = stackalloc byte[8];
                    otelSpan.ParentSpanId.CopyTo(parentSpanIdBytes);
                    parentSpanIdString = ByteString.CopyFrom(parentSpanIdBytes.ToArray());
                }

                return(new Proto.Trace.V1.Span
                {
                    Name = new TruncatableString {
                        Value = otelSpan.Name
                    },

                    // TODO: Utilize new Span.Types.SpanKind below when updated protos are incorporated, also confirm default for SpanKind.Internal
                    Kind = otelSpan.Kind == SpanKind.Client || otelSpan.Kind == SpanKind.Producer ?
                           Proto.Trace.V1.Span.Types.SpanKind.Client :
                           Proto.Trace.V1.Span.Types.SpanKind.Server,

                    TraceId = ByteString.CopyFrom(traceIdBytes.ToArray()),
                    SpanId = ByteString.CopyFrom(spanIdBytes.ToArray()),
                    ParentSpanId = parentSpanIdString,

                    StartTime = otelSpan.StartTimestamp.ToTimestamp(),
                    EndTime = otelSpan.EndTimestamp.ToTimestamp(),
                    Status = !otelSpan.Status.IsValid
                        ? null
                        : new OpenTelemetry.Proto.Trace.V1.Status
                    {
                        Code = (int)otelSpan.Status.CanonicalCode,
                        Message = otelSpan.Status.Description ?? string.Empty,
                    },
                    SameProcessAsParentSpan = otelSpan.ParentSpanId != default,
                    ChildSpanCount = null,
                    Attributes = FromAttributes(otelSpan.Attributes),
                    TimeEvents = FromITimeEvents(otelSpan.Events),
                    Links = new Proto.Trace.V1.Span.Types.Links
                    {
                        Link = { otelSpan.Links.Select(FromILink), },
                    },
                });
            }
Example #2
0
        private void AddTrace(HttpListenerContext _Context, bool _bNewSpan, Action <string> _ErrorMessageAction = null)
        {
            //Start
            if (_bNewSpan)
            {
                _Context.Request.Headers.Set("span-start-time", DateTime.Now.ToString());
            }
            //End
            else
            {
                var TraceID = _Context.Request.Headers.Get("trace-id");
                if (TraceID == null || TraceID.Length == 0)
                {
                    //It is a new trace
                    TraceID = Guid.NewGuid().ToString("N");
                }

                string ParentSpanID = null;
                string SpanID       = _Context.Request.Headers.Get("span-id");
                if (SpanID != null && SpanID.Length > 0)
                {
                    ParentSpanID = SpanID;
                }
                SpanID = GetRandomHexNumber(16);

                _Context.Request.Headers.Set("trace-id", TraceID);
                _Context.Request.Headers.Set("span-id", SpanID);

                var LegitSpanName = new SpanName(ProjectName.ProjectId, TraceID, SpanID);
                var TruncString   = new TruncatableString
                {
                    Value = _Context.Request.HttpMethod + "->" + _Context.Request.Url.AbsolutePath,
                    TruncatedByteCount = 0
                };

                Timestamp StartTime = null;
                try
                {
                    StartTime = Timestamp.FromDateTimeOffset(DateTime.Parse(_Context.Request.Headers.Get("span-start-time")));
                }
                catch (Exception ex)
                {
                    _ErrorMessageAction?.Invoke("BTracingServiceGC->AddTrace: " + ex.Message + ", Trace: " + ex.StackTrace);
                }

                var Span = new Span
                {
                    SpanName    = LegitSpanName,
                    DisplayName = TruncString,
                    SpanId      = SpanID,
                    StartTime   = StartTime ?? Timestamp.FromDateTimeOffset(DateTime.Now),
                    EndTime     = Timestamp.FromDateTimeOffset(DateTime.Now),
                    Attributes  = new Span.Types.Attributes()
                };
                if (ParentSpanID != null)
                {
                    Span.ParentSpanId = ParentSpanID;
                }

                AddEntryToSpan(Span, "Service Name", ProgramUniqueID);
                AddEntryToSpan(Span, "HTTP Method", _Context.Request.HttpMethod);
                AddEntryToSpan(Span, "HTTP URL", _Context.Request.Url.AbsoluteUri);
                AddEntryToSpan(Span, "HTTP Path", _Context.Request.Url.AbsolutePath);

                lock (Spans)
                {
                    Spans.Add(Span);
                }
            }
        }