private void LogFunctionResult(IEnumerable <KeyValuePair <string, object> > state, LogLevel logLevel, Exception exception) { IDictionary <string, object> scopeProps = DictionaryLoggerScope.GetMergedStateDictionary() ?? new Dictionary <string, object>(); // log associated exception details KeyValuePair <string, object>[] stateProps = state as KeyValuePair <string, object>[] ?? state.ToArray(); if (exception != null) { LogException(logLevel, stateProps, exception, null); } ApplyFunctionResultActivityTags(stateProps, scopeProps); IOperationHolder <RequestTelemetry> requestOperation = (IOperationHolder <RequestTelemetry>)scopeProps.GetValueOrDefault(OperationContext); if (requestOperation != null) { // We somehow never started the operation, perhaps, it was auto-tracked by the AI SDK // so there's no way to complete it. RequestTelemetry requestTelemetry = requestOperation.Telemetry; requestTelemetry.Success = exception == null; requestTelemetry.ResponseCode = "0"; // Note: we do not have to set Duration, StartTime, etc. These are handled by the call to Stop() _telemetryClient.StopOperation(requestOperation); } }
// Applies scope properties; filters most system properties, which are used internally private static void ApplyScopeProperties(ISupportProperties telemetry) { var scopeProperties = DictionaryLoggerScope.GetMergedStateDictionary(); var customScopeProperties = scopeProperties.Where(p => !SystemScopeKeys.Contains(p.Key, StringComparer.Ordinal)); ApplyProperties(telemetry, customScopeProperties, LogConstants.CustomPropertyPrefix); }
public IDisposable BeginScope <TState>(TState state) { if (state == null) { throw new ArgumentNullException(nameof(state)); } StartTelemetryIfFunctionInvocation(state as IDictionary <string, object>); return(DictionaryLoggerScope.Push(state)); }
public static IDisposable Push(object state) { IDictionary <string, object> stateValues; if (state is IEnumerable <KeyValuePair <string, object> > stateEnum) { // Convert this to a dictionary as we have scenarios where we cannot have duplicates. In this // case, if there are dupes, the later entry wins. stateValues = new Dictionary <string, object>(); foreach (var entry in stateEnum) { stateValues[entry.Key] = entry.Value; } } else { // There's nothing we can do with other states. return(null); } Current = new DictionaryLoggerScope(new ReadOnlyDictionary <string, object>(stateValues), Current); return(new DisposableScope()); }
private DictionaryLoggerScope(IReadOnlyDictionary <string, object> state, DictionaryLoggerScope parent) { State = state; Parent = parent; }