//Push finished spans into the reservoir. When the root span finishes, log them only if they're sampled. public void SpanFinished(LambdaSpan span) { lock (_spanReservoirLock) { _spanReservoir.AddFirst(span); } }
private IDictionary <string, object> CreateUserAttributes(LambdaSpan span) { var attributes = new Dictionary <string, object>(); var errorKind = span.GetSpanLogEntry("error.kind"); if (errorKind != null) { attributes.Add("error.kind", errorKind.Value); } return(attributes); }
public ISpan StartManual() { LambdaTracer tracer = LambdaTracer.Instance as LambdaTracer; ISpan activeSpan = tracer.ActiveSpan; ISpanContext parentSpanContext = null; if (!_ignoreActiveSpan && _parent == null && activeSpan != null) { AddReference(References.ChildOf, activeSpan.Context); parentSpanContext = activeSpan.Context; } else if (_parent != null) { parentSpanContext = _parent; } LambdaSpan parentSpan = null; if (parentSpanContext is LambdaSpanContext) { parentSpan = ((LambdaSpanContext)parentSpanContext).GetSpan(); } var guid = GuidGenerator.GenerateNewRelicGuid(); LambdaSpan newSpan; if (parentSpan != null) { newSpan = new LambdaSpan(_operationName, DateTimeOffset.UtcNow, _tags, parentSpan, guid); } else { var rootSpan = new LambdaRootSpan(_operationName, DateTimeOffset.UtcNow, _tags, guid, new DataCollector(_logger, tracer.DebugMode), new TransactionState(), new PrioritySamplingState(), new DistributedTracingState()); if (parentSpanContext is LambdaPayloadContext payloadContext) { rootSpan.ApplyLambdaPayloadContext(payloadContext); } else { rootSpan.ApplyAdaptiveSampling(tracer.AdaptiveSampler); } newSpan = rootSpan; } LambdaSpanContext spanContext = new LambdaSpanContext(newSpan); newSpan.SetContext(spanContext); return(newSpan); }
internal void RecordErrors(LambdaSpan span) { var errorEventLogEntry = span.GetSpanLogEntry("event"); if (errorEventLogEntry == null || !"error".Equals(errorEventLogEntry.Value)) { return; } var errorObjectLogEntry = span.GetSpanLogEntry("error.object"); if (errorObjectLogEntry == null) { return; } var errorMessageLogEntry = span.GetSpanLogEntry("message"); var errorObjectIsThrowable = errorObjectLogEntry.Value is Exception; if (errorMessageLogEntry == null && !errorObjectIsThrowable) { return; } var errorClass = errorObjectLogEntry.Value.GetType().Name; var errorMessage = GetErrorMessage(errorMessageLogEntry, errorObjectLogEntry); var userAttributes = CreateUserAttributes(span); var txnState = span.RootSpan.TransactionState; var errorEvent = new ErrorEventBuilder() .SetErrorClass(errorClass) .SetErrorMessage(errorMessage) .SetTransactionDuration(txnState.Duration) .SetTimestamp(errorObjectLogEntry.Timestamp) .SetUserAttributes(userAttributes) .SetTransactionName(txnState.TransactionName) .SetTransactionGuid(txnState.TransactionId) .SetDistributedTraceIntrinsics(span.Intrinsics) .CreateError(); _errorEvents.Add(errorEvent); LogEntry errorStack = span.GetSpanLogEntry("stack"); if (errorStack == null && !errorObjectIsThrowable) { return; } string stackTrace = GetStackTrace(errorStack, errorObjectLogEntry); var errorTrace = new ErrorTraceBuilder() .SetErrorMessage(errorMessage) .SetErrorType(errorClass) .SetTransactionGuid(txnState.TransactionId) .SetTransactionName(txnState.TransactionName) .SetDistributedTraceIntrinsics(span.Intrinsics) .SetUserAttributes(userAttributes) .SetTimestamp(errorObjectLogEntry.Timestamp) .SetStackTrace(stackTrace) .CreateErrorTrace(); _errorTraces.Add(errorTrace); }
public LambdaSpan(string operationName, DateTimeOffset timestamp, IDictionary <string, object> tags, LambdaSpan parentSpan, string guid) { _type = "Span"; _operationName = operationName; TimeStamp = timestamp; Tags = tags; _guid = guid; SpanLog = new Dictionary <string, LogEntry>(); if (parentSpan != null) { _parentId = parentSpan.Guid(); RootSpan = parentSpan.RootSpan; } else { //This is the root span _parentId = null; RootSpan = (LambdaRootSpan)this; } }
public LambdaSpanContext(LambdaSpan span) { _span = span; }