Пример #1
0
        public void Log <TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func <TState, Exception, string> formatter)
        {
            LogMessage logMessage = new LogMessage
            {
                Level            = logLevel,
                EventId          = eventId,
                State            = state as IEnumerable <KeyValuePair <string, object> >,
                Scope            = _scopeProvider.GetScopeDictionaryOrNull(),
                Exception        = exception,
                FormattedMessage = formatter(state, exception),
                Category         = Category,
                Timestamp        = DateTime.UtcNow
            };

            lock (_syncLock)
            {
                _logMessages.Add(logMessage);
            }
        }
        public void Log <TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func <TState, Exception, string> formatter)
        {
            if (!IsEnabled(logLevel))
            {
                return;
            }

            // Make sure we have something to log
            string formattedMessage = formatter?.Invoke(state, exception);

            if (string.IsNullOrEmpty(formattedMessage) && exception == null)
            {
                return;
            }

            (string exceptionType, string exceptionMessage, string exceptionDetails) = exception.GetExceptionDetails();
            if (exception != null)
            {
                formattedMessage = Sanitizer.Sanitize(formattedMessage);
            }

            // enumerate all the state values once, capturing the values we'll use below
            // last one wins
            string stateFunctionName = null;

            if (state is IEnumerable <KeyValuePair <string, object> > stateProps)
            {
                foreach (var kvp in stateProps)
                {
                    if (Utility.IsFunctionName(kvp))
                    {
                        stateFunctionName = kvp.Value?.ToString();
                    }
                }
            }

            var    scopeProps   = _scopeProvider.GetScopeDictionaryOrNull();
            string functionName = stateFunctionName;

            if (string.IsNullOrEmpty(functionName))
            {
                if (Utility.TryGetFunctionName(scopeProps, out string scopeFunctionName))
                {
                    functionName = scopeFunctionName;
                }
            }

            // Build up a JSON string for the Azure Monitor 'properties' bag
            StringWriter sw = new StringWriter();

            using (JsonTextWriter writer = new JsonTextWriter(sw)
            {
                Formatting = Formatting.None
            })
            {
                writer.WriteStartObject();
                WritePropertyIfNotNull(writer, "appName", _appServiceOptions.CurrentValue.AppName);
                WritePropertyIfNotNull(writer, "roleInstance", _roleInstance);
                WritePropertyIfNotNull(writer, "message", formattedMessage);
                WritePropertyIfNotNull(writer, "category", _category);
                WritePropertyIfNotNull(writer, "hostVersion", _hostVersion);
                WritePropertyIfNotNull(writer, "functionInvocationId", Utility.GetValueFromScope(scopeProps, ScopeKeys.FunctionInvocationId));
                WritePropertyIfNotNull(writer, "functionName", functionName);
                WritePropertyIfNotNull(writer, "hostInstanceId", _hostInstanceId);
                WritePropertyIfNotNull(writer, "activityId", Utility.GetValueFromScope(scopeProps, ScriptConstants.LogPropertyActivityIdKey));
                WritePropertyIfNotNull(writer, "level", logLevel.ToString());
                WritePropertyIfNotNull(writer, "levelId", (int)logLevel);
                WritePropertyIfNotNull(writer, "processId", _processId);
                WritePropertyIfNotNull(writer, nameof(exceptionDetails), exceptionDetails);
                WritePropertyIfNotNull(writer, nameof(exceptionMessage), exceptionMessage);
                WritePropertyIfNotNull(writer, nameof(exceptionType), exceptionType);

                // Only write the event if it's relevant
                if (eventId.Id != 0 || !string.IsNullOrEmpty(eventId.Name))
                {
                    WriteProperty(writer, "eventId", eventId.Id);
                    WriteProperty(writer, "eventName", eventId.Name);
                }

                writer.WriteEndObject();
            }

            _eventGenerator.LogAzureMonitorDiagnosticLogEvent(logLevel, _hostNameProvider.Value, AzureMonitorOperationName, AzureMonitorCategoryName, _regionName, sw.ToString());
        }
Пример #3
0
        public void Log <TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func <TState, Exception, string> formatter)
        {
            if (!IsEnabled(logLevel) || _isUserFunction)
            {
                return;
            }

            // enumerate all the state values once, capturing the values we'll use below
            // last one wins
            string stateSourceValue  = null;
            string stateFunctionName = null;
            string stateEventName    = null;
            string stateActivityId   = null;

            if (state is IEnumerable <KeyValuePair <string, object> > stateProps)
            {
                foreach (var kvp in stateProps)
                {
                    if (string.Equals(kvp.Key, ScriptConstants.LogPropertySourceKey, StringComparison.OrdinalIgnoreCase))
                    {
                        stateSourceValue = kvp.Value?.ToString();
                    }
                    else if (string.Equals(kvp.Key, ScriptConstants.LogPropertyIsUserLogKey, StringComparison.OrdinalIgnoreCase))
                    {
                        if ((bool)kvp.Value)
                        {
                            return;
                        }
                    }
                    else if (Utility.IsFunctionName(kvp))
                    {
                        stateFunctionName = kvp.Value?.ToString();
                    }
                    else if (string.Equals(kvp.Key, ScriptConstants.LogPropertyEventNameKey, StringComparison.OrdinalIgnoreCase))
                    {
                        stateEventName = kvp.Value?.ToString();
                    }
                    else if (string.Equals(kvp.Key, ScriptConstants.LogPropertyActivityIdKey, StringComparison.OrdinalIgnoreCase))
                    {
                        stateActivityId = kvp.Value?.ToString();
                    }
                }
            }

            // propagate special exceptions through the EventManager
            string source = _categoryName ?? stateSourceValue;

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

            // If we don't have a message, there's nothing to log.
            string formattedMessage = formatter?.Invoke(state, exception);

            if (string.IsNullOrEmpty(formattedMessage))
            {
                return;
            }

            var    scopeProps   = _scopeProvider.GetScopeDictionaryOrNull();
            string functionName = _functionName ?? stateFunctionName ?? string.Empty;

            if (string.IsNullOrEmpty(functionName) && scopeProps?.Count > 0)
            {
                if (Utility.TryGetFunctionName(scopeProps, out string scopeFunctionName))
                {
                    functionName = scopeFunctionName;
                }
            }

            string invocationId = string.Empty;
            object scopeValue   = null;

            if (scopeProps != null && scopeProps.TryGetValue(ScriptConstants.LogPropertyFunctionInvocationIdKey, out scopeValue) && scopeValue != null)
            {
                invocationId = scopeValue.ToString();
            }

            // 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 summary         = formattedMessage ?? string.Empty;
            string eventName       = !string.IsNullOrEmpty(eventId.Name) ? eventId.Name : stateEventName ?? string.Empty;
            string activityId      = stateActivityId ?? string.Empty;
            string subscriptionId  = _appServiceOptions.CurrentValue.SubscriptionId ?? string.Empty;
            string appName         = _appServiceOptions.CurrentValue.AppName ?? string.Empty;
            string runtimeSiteName = _appServiceOptions.CurrentValue.RuntimeSiteName ?? string.Empty;
            string slotName        = _appServiceOptions.CurrentValue.SlotName ?? string.Empty;

            string innerExceptionType    = string.Empty;
            string innerExceptionMessage = string.Empty;
            string details = string.Empty;

            if (exception != null)
            {
                // Populate details from the exception.
                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();
                formattedMessage      = Sanitizer.Sanitize(formattedMessage);
                innerExceptionMessage = innerExceptionMessage ?? string.Empty;
            }

            _eventGenerator.LogFunctionTraceEvent(logLevel, subscriptionId, appName, functionName, eventName, source, details, summary, innerExceptionType, innerExceptionMessage, invocationId, _hostInstanceId, activityId, runtimeSiteName, slotName, DateTime.UtcNow);
        }