public void Log <TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func <TState, Exception, string> formatter)
        {
            // propagate special exceptions through the EventManager
            string source = _categoryName ?? Utility.GetValueFromState(state, ScriptConstants.LogPropertySourceKey);

            if (exception is FunctionIndexingException && _eventManager != null)
            {
                _eventManager.Publish(new FunctionIndexingEvent("FunctionIndexingException", source, exception));
            }

            // User logs are not logged to system logs.
            if (!IsEnabled(logLevel) || IsUserLog(state))
            {
                return;
            }

            string formattedMessage = formatter?.Invoke(state, exception);

            // If we don't have a message, there's nothing to log.
            if (string.IsNullOrEmpty(formattedMessage))
            {
                return;
            }

            IDictionary <string, object> scopeProps = DictionaryLoggerScope.GetMergedStateDictionary() ?? new Dictionary <string, object>();

            // Apply standard event properties
            // Note: we must be sure to default any null values to empty string
            // otherwise the ETW event will fail to be persisted (silently)
            string subscriptionId        = _environment.GetSubscriptionId() ?? string.Empty;
            string appName               = _environment.GetAzureWebsiteUniqueSlotName() ?? string.Empty;
            string summary               = Sanitizer.Sanitize(formattedMessage) ?? string.Empty;
            string innerExceptionType    = string.Empty;
            string innerExceptionMessage = string.Empty;
            string functionName          = _functionName;
            string eventName             = !string.IsNullOrEmpty(eventId.Name) ? eventId.Name : Utility.GetValueFromState(state, ScriptConstants.LogPropertyEventNameKey);
            string functionInvocationId  = Utility.GetValueFromScope(scopeProps, ScriptConstants.LogPropertyFunctionInvocationIdKey) ?? string.Empty;
            string hostInstanceId        = _hostInstanceId;
            string activityId            = Utility.GetValueFromState(state, ScriptConstants.LogPropertyActivityIdKey);
            string runtimeSiteName       = _environment.GetRuntimeSiteName() ?? string.Empty;

            // Populate details from the exception.
            string details = string.Empty;

            if (exception != null)
            {
                if (string.IsNullOrEmpty(functionName) && exception is FunctionInvocationException fex)
                {
                    functionName = string.IsNullOrEmpty(fex.MethodName) ? string.Empty : fex.MethodName.Replace("Host.Functions.", string.Empty);
                }

                (innerExceptionType, innerExceptionMessage, details) = exception.GetExceptionDetails();
                innerExceptionMessage = innerExceptionMessage ?? string.Empty;
            }

            _eventGenerator.LogFunctionTraceEvent(logLevel, subscriptionId, appName, functionName, eventName, source, details, summary, innerExceptionType, innerExceptionMessage, functionInvocationId, hostInstanceId, activityId, runtimeSiteName);
        }
        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());
        }
 public IDisposable BeginScope<TState>(TState state) => DictionaryLoggerScope.Push(state);
Beispiel #4
0
        public void Log <TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func <TState, Exception, string> formatter)
        {
            // User logs are not logged to system logs.
            if (!IsEnabled(logLevel) || IsUserLog(state))
            {
                return;
            }

            string formattedMessage = formatter?.Invoke(state, exception);

            // If we don't have a message, there's nothing to log.
            if (string.IsNullOrEmpty(formattedMessage))
            {
                return;
            }

            IDictionary <string, object> scopeProps = DictionaryLoggerScope.GetMergedStateDictionary() ?? new Dictionary <string, object>();

            // Apply standard event properties
            // Note: we must be sure to default any null values to empty string
            // otherwise the ETW event will fail to be persisted (silently)
            string subscriptionId        = _subscriptionId ?? string.Empty;
            string appName               = _appName ?? string.Empty;
            string source                = _categoryName ?? Utility.GetValueFromState(state, ScriptConstants.LogPropertySourceKey);
            string summary               = Sanitizer.Sanitize(formattedMessage) ?? string.Empty;
            string innerExceptionType    = string.Empty;
            string innerExceptionMessage = string.Empty;
            string functionName          = _functionName;
            string eventName             = Utility.GetValueFromState(state, ScriptConstants.LogPropertyEventNameKey);
            string functionInvocationId  = Utility.GetValueFromScope(scopeProps, ScriptConstants.LogPropertyFunctionInvocationIdKey) ?? string.Empty;
            string hostInstanceId        = _hostInstanceId;
            string activityId            = Utility.GetValueFromState(state, ScriptConstants.LogPropertyActivityIdKey);

            // Populate details from the exception.
            string details = string.Empty;

            if (exception != null)
            {
                details = Sanitizer.Sanitize(exception.ToFormattedString());
                if (string.IsNullOrEmpty(functionName) && exception is FunctionInvocationException fex)
                {
                    functionName = string.IsNullOrEmpty(fex.MethodName) ? string.Empty : fex.MethodName.Replace("Host.Functions.", string.Empty);
                }

                Exception innerException = exception.InnerException;
                while (innerException != null && innerException.InnerException != null)
                {
                    innerException = innerException.InnerException;
                }

                if (innerException != null)
                {
                    GetExceptionDetails(innerException, out innerExceptionType, out innerExceptionMessage);
                }
                else
                {
                    GetExceptionDetails(exception, out innerExceptionType, out innerExceptionMessage);
                }
            }

            _eventGenerator.LogFunctionTraceEvent(logLevel, subscriptionId, appName, functionName, eventName, source, details, summary, innerExceptionType, innerExceptionMessage, functionInvocationId, hostInstanceId, activityId);
        }
 private DictionaryLoggerScope(IReadOnlyDictionary <string, object> state, DictionaryLoggerScope parent)
 {
     State  = state;
     Parent = parent;
 }