public virtual IEnumerable <ILoggerProvider> CreateLoggerProviders(string hostInstanceId, ScriptHostConfiguration scriptConfig, ScriptSettingsManager settingsManager,
                                                                           Func <bool> isFileLoggingEnabled, Func <bool> isPrimary)
        {
            IList <ILoggerProvider> providers = new List <ILoggerProvider>();

            IMetricsLogger metricsLogger = scriptConfig.HostConfig.GetService <IMetricsLogger>();

            // Automatically register App Insights if the key is present
            if (!string.IsNullOrEmpty(settingsManager?.ApplicationInsightsInstrumentationKey))
            {
                metricsLogger?.LogEvent(MetricEventNames.ApplicationInsightsEnabled);

                ITelemetryClientFactory clientFactory = scriptConfig.HostConfig.GetService <ITelemetryClientFactory>() ??
                                                        new ScriptTelemetryClientFactory(settingsManager.ApplicationInsightsInstrumentationKey, scriptConfig.ApplicationInsightsSamplingSettings, scriptConfig.LogFilter.Filter);

                providers.Add(new ApplicationInsightsLoggerProvider(clientFactory));
            }
            else
            {
                metricsLogger?.LogEvent(MetricEventNames.ApplicationInsightsDisabled);
            }

            providers.Add(new FunctionFileLoggerProvider(hostInstanceId, scriptConfig.RootLogPath, isFileLoggingEnabled, isPrimary));
            providers.Add(new HostFileLoggerProvider(hostInstanceId, scriptConfig.RootLogPath, isFileLoggingEnabled));

            if (settingsManager.Configuration.GetSection("host:logger:consoleLoggingMode").Value == "always")
            {
                providers.Add(new ConsoleLoggerProvider(scriptConfig.LogFilter.Filter, includeScopes: true));
            }

            return(providers);
        }
        /// <summary>
        /// Performs all required initialization on the host.
        /// Must be called before the host is started.
        /// </summary>
        public async Task InitializeAsync(CancellationToken cancellationToken = default)
        {
            _stopwatch = ValueStopwatch.StartNew();
            using (_metricsLogger.LatencyEvent(MetricEventNames.HostStartupLatency))
            {
                PreInitialize();
                HostInitializing?.Invoke(this, EventArgs.Empty);

                _workerRuntime = _workerRuntime ?? _environment.GetEnvironmentVariable(EnvironmentSettingNames.FunctionWorkerRuntime);

                // get worker config information and check to see if worker should index or not
                var workerConfigs = _languageWorkerOptions.Value.WorkerConfigs;

                bool workerIndexing = Utility.CanWorkerIndex(workerConfigs, _environment);

                // Generate Functions
                IEnumerable <FunctionMetadata> functionMetadataList = GetFunctionsMetadata(workerIndexing);

                if (!_environment.IsPlaceholderModeEnabled())
                {
                    string runtimeStack = _workerRuntime;

                    if (!string.IsNullOrEmpty(runtimeStack))
                    {
                        // Appending the runtime version is currently only enabled for linux consumption. This will be eventually enabled for
                        // Windows Consumption as well.
                        string runtimeVersion = _environment.GetEnvironmentVariable(RpcWorkerConstants.FunctionWorkerRuntimeVersionSettingName);

                        if (!string.IsNullOrEmpty(runtimeVersion))
                        {
                            runtimeStack = string.Concat(runtimeStack, "-", runtimeVersion);
                        }
                    }

                    _metricsLogger.LogEvent(string.Format(MetricEventNames.HostStartupRuntimeLanguage, Sanitizer.Sanitize(runtimeStack)));

                    Utility.LogAutorestGeneratedJsonIfExists(ScriptOptions.RootScriptPath, _logger);
                }

                IsFunctionDataCacheEnabled = GetIsFunctionDataCacheEnabled();

                await InitializeFunctionDescriptorsAsync(functionMetadataList, cancellationToken);

                if (!workerIndexing)
                {
                    // Initialize worker function invocation dispatcher only for valid functions after creating function descriptors
                    // Dispatcher not needed for codeless function.
                    // Disptacher needed for non-dotnet codeless functions
                    var filteredFunctionMetadata = functionMetadataList.Where(m => !Utility.IsCodelessDotNetLanguageFunction(m));
                    await _functionDispatcher.InitializeAsync(Utility.GetValidFunctions(filteredFunctionMetadata, Functions), cancellationToken);
                }

                GenerateFunctions();
                ScheduleFileSystemCleanup();
            }
        }
        public void Decorator_LogEventWithMetricEvent_Called()
        {
            Guid                 invocationId = Guid.NewGuid();
            FunctionMetadata     meta         = new FunctionMetadata();
            FunctionStartedEvent evt          = new FunctionStartedEvent(invocationId, meta);

            _metricsLogger.Setup(a => a.LogEvent(evt));
            _metricsLoggerDecorator.LogEvent(evt);
            _metricsLogger.Verify(a => a.LogEvent(evt), Times.Once());
            _metricsLogger.Reset();
        }
        internal static void LogInvocationMetrics(IMetricsLogger metrics, Collection <BindingMetadata> bindings)
        {
            metrics.LogEvent(MetricEventNames.FunctionInvoke);

            // log events for each of the binding types used
            foreach (var binding in bindings)
            {
                string eventName = binding.IsTrigger ?
                                   string.Format(MetricEventNames.FunctionBindingTypeFormat, binding.Type) :
                                   string.Format(MetricEventNames.FunctionBindingTypeDirectionFormat, binding.Type, binding.Direction);
                metrics.LogEvent(eventName);
            }
        }
        /// <summary>
        /// Perform any early initialization operations.
        /// </summary>
        private void PreInitialize()
        {
            // Log whether App Insights is enabled
            if (!string.IsNullOrEmpty(_settingsManager.ApplicationInsightsInstrumentationKey))
            {
                _metricsLogger.LogEvent(MetricEventNames.ApplicationInsightsEnabled);
            }
            else
            {
                _metricsLogger.LogEvent(MetricEventNames.ApplicationInsightsDisabled);
            }

            InitializeFileSystem();
        }
        /// <summary>
        /// Performs all required initialization on the host.
        /// Must be called before the host is started.
        /// </summary>
        public async Task InitializeAsync(CancellationToken cancellationToken = default)
        {
            _stopwatch.Start();
            using (_metricsLogger.LatencyEvent(MetricEventNames.HostStartupLatency))
            {
                PreInitialize();
                HostInitializing?.Invoke(this, EventArgs.Empty);

                // Generate Functions
                IEnumerable <FunctionMetadata> functionMetadataList = GetFunctionsMetadata();

                _workerRuntime = _workerRuntime ?? Utility.GetWorkerRuntime(functionMetadataList);

                if (!_environment.IsPlaceholderModeEnabled())
                {
                    string runtimeStack = _workerRuntime;

                    if (!string.IsNullOrEmpty(runtimeStack))
                    {
                        // Appending the runtime version is currently only enabled for linux consumption. This will be eventually enabled for
                        // Windows Consumption as well.
                        string runtimeVersion = _environment.GetEnvironmentVariable(RpcWorkerConstants.FunctionWorkerRuntimeVersionSettingName);

                        if (!string.IsNullOrEmpty(runtimeVersion))
                        {
                            runtimeStack = string.Concat(runtimeStack, "-", runtimeVersion);
                        }
                    }

                    _metricsLogger.LogEvent(string.Format(MetricEventNames.HostStartupRuntimeLanguage, runtimeStack));

                    Utility.LogAutorestGeneratedJsonIfExists(ScriptOptions.RootScriptPath, _logger);
                }

                var directTypes = GetDirectTypes(functionMetadataList);
                await InitializeFunctionDescriptorsAsync(functionMetadataList, cancellationToken);

                // Initialize worker function invocation dispatcher only for valid functions after creating function descriptors
                // Dispatcher not needed for non-proxy codeless function.
                // Disptacher needed for non-dotnet codeless functions
                var filteredFunctionMetadata = functionMetadataList.Where(m => m.IsProxy() || !Utility.IsCodelessDotNetLanguageFunction(m));
                await _functionDispatcher.InitializeAsync(Utility.GetValidFunctions(filteredFunctionMetadata, Functions), cancellationToken);

                GenerateFunctions(directTypes);

                ScheduleFileSystemCleanup();
            }
        }
Exemple #7
0
        // Called on success and failure
        public void End(bool success)
        {
            startedEvent.Success = success;
            string  eventName = success ? MetricEventNames.FunctionInvokeSucceeded : MetricEventNames.FunctionInvokeFailed;
            dynamic data      = new JObject();

            data.Language     = startedEvent.FunctionMetadata.Language;
            data.FunctionName = _metadata != null ? _metadata.Name : string.Empty;
            data.Success      = success;
            string jsonData = data.ToString();

            startedEvent.Data = jsonData;
            _metrics.LogEvent(eventName, startedEvent.FunctionName, jsonData);

            _metrics.EndEvent(startedEvent);

            if (invokeLatencyEvent != null)
            {
                MetricEvent metricEvent = invokeLatencyEvent as MetricEvent;
                if (metricEvent != null)
                {
                    metricEvent.Data = jsonData;
                }
                _metrics.EndEvent(invokeLatencyEvent);
            }
        }
Exemple #8
0
        private void EndFunction(FunctionInstanceLogEntry item)
        {
            item.Properties.TryGetValue(Key, out (FunctionStartedEvent, object)invocationTuple);

            bool success      = item.ErrorDetails == null;
            var  startedEvent = invocationTuple.Item1;

            startedEvent.Success = success;

            var    function     = startedEvent.FunctionMetadata;
            string eventName    = success ? MetricEventNames.FunctionInvokeSucceeded : MetricEventNames.FunctionInvokeFailed;
            string functionName = function != null ? function.Name : string.Empty;
            string data         = string.Format(Microsoft.Azure.WebJobs.Script.Properties.Resources.FunctionInvocationMetricsData, startedEvent.FunctionMetadata.Language, functionName, success, Stopwatch.IsHighResolution);

            _metrics.LogEvent(eventName, startedEvent.FunctionName, data);

            startedEvent.Data = data;
            _metrics.EndEvent(startedEvent);

            var invokeLatencyEvent = invocationTuple.Item2;

            if (invokeLatencyEvent is MetricEvent metricEvent)
            {
                metricEvent.Data = data;
            }

            _metrics.EndEvent(invokeLatencyEvent);
        }
        internal object LogInvocationMetrics(FunctionMetadata metadata)
        {
            // log events for each of the binding types used
            foreach (var binding in metadata.Bindings)
            {
                string eventName = _bindingMetricEventNames.GetOrAdd(binding, (existing) =>
                {
                    return(binding.IsTrigger ?
                           string.Format(MetricEventNames.FunctionBindingTypeFormat, binding.Type) :
                           string.Format(MetricEventNames.FunctionBindingTypeDirectionFormat, binding.Type, binding.Direction));
                });
                _metrics.LogEvent(eventName, metadata.Name);
            }

            return(_metrics.BeginEvent(MetricEventNames.FunctionInvokeLatency, metadata.Name));
        }
Exemple #10
0
        // Called on success and failure
        public void End(bool success)
        {
            _startedEvent.Success = success;
            string eventName = success ? MetricEventNames.FunctionInvokeSucceeded : MetricEventNames.FunctionInvokeFailed;

            var data = new JObject
            {
                ["Language"]     = _startedEvent.FunctionMetadata.Language,
                ["FunctionName"] = _metadata != null ? _metadata.Name : string.Empty,
                ["Success"]      = success,
                ["IsStopwatchHighResolution"] = Stopwatch.IsHighResolution
            };

            string jsonData = data.ToString();

            _startedEvent.Data = jsonData;
            _metrics.LogEvent(eventName, _startedEvent.FunctionName, jsonData);

            _metrics.EndEvent(_startedEvent);

            if (_invokeLatencyEvent is MetricEvent metricEvent)
            {
                metricEvent.Data = jsonData;
            }

            _metrics.EndEvent(_invokeLatencyEvent);
        }
Exemple #11
0
        private void RejectRequest(HttpContext httpContext, IMetricsLogger metricsLogger)
        {
            metricsLogger.LogEvent(MetricEventNames.FunctionInvokeThrottled);

            httpContext.Response.StatusCode = 429;
            httpContext.Response.Headers.Add(ScriptConstants.AntaresScaleOutHeaderName, "1");
        }
        public void Configure(HttpWorkerOptions options)
        {
            IConfigurationSection jobHostSection = _configuration.GetSection(ConfigurationSectionNames.JobHost);
            var httpWorkerSection    = jobHostSection.GetSection(ConfigurationSectionNames.HttpWorker);
            var customHandlerSection = jobHostSection.GetSection(ConfigurationSectionNames.CustomHandler);

            if (httpWorkerSection.Exists() && customHandlerSection.Exists())
            {
                _logger.LogWarning($"Both {ConfigurationSectionNames.HttpWorker} and {ConfigurationSectionNames.CustomHandler} sections are spefified in {ScriptConstants.HostMetadataFileName} file. {ConfigurationSectionNames.CustomHandler} takes precedence.");
            }

            if (customHandlerSection.Exists())
            {
                _metricsLogger.LogEvent(MetricEventNames.CustomHandlerConfiguration);
                ConfigureWorkerDescription(options, customHandlerSection);
                if (options.Type == CustomHandlerType.None)
                {
                    // CustomHandlerType.None is only for maitaining backward compatibilty with httpWorker section.
                    _logger.LogWarning($"CustomHandlerType {CustomHandlerType.None} is not supported. Defaulting to {CustomHandlerType.Http}.");
                    options.Type = CustomHandlerType.Http;
                }
                return;
            }

            if (httpWorkerSection.Exists())
            {
                // TODO: Add aka.ms/link to new docs
                _logger.LogWarning($"Section {ConfigurationSectionNames.HttpWorker} will be deprecated. Please use {ConfigurationSectionNames.CustomHandler} section.");
                ConfigureWorkerDescription(options, httpWorkerSection);
                // Explicity set this to None to differentiate between customHandler and httpWorker options.
                options.Type = CustomHandlerType.None;
            }
        }
Exemple #13
0
        protected override HttpResponseMessage RejectRequest(HttpRequestMessage request)
        {
            var function = request.GetPropertyOrDefault <FunctionDescriptor>(ScriptConstants.AzureFunctionsHttpFunctionKey);

            _metricsLogger.LogEvent(MetricEventNames.FunctionInvokeThrottled, function.Name);

            return(base.RejectRequest(request));
        }
        /// <summary>
        /// Adds additional <see cref="ILoggerProvider"/>s to the <see cref="ILoggerFactory"/>.
        /// </summary>
        /// <param name="factory">The <see cref="ILoggerFactory"/>.</param>
        /// <param name="scriptConfig">The configuration.</param>
        public virtual void AddLoggerProviders(ILoggerFactory factory, ScriptHostConfiguration scriptConfig, ScriptSettingsManager settingsManager)
        {
            IMetricsLogger metricsLogger = scriptConfig.HostConfig.GetService <IMetricsLogger>();

            // Automatically register App Insights if the key is present
            if (!string.IsNullOrEmpty(settingsManager?.ApplicationInsightsInstrumentationKey))
            {
                metricsLogger?.LogEvent(MetricEventNames.ApplicationInsightsEnabled);

                ITelemetryClientFactory clientFactory = scriptConfig.HostConfig.GetService <ITelemetryClientFactory>() ??
                                                        new ScriptTelemetryClientFactory(settingsManager.ApplicationInsightsInstrumentationKey, scriptConfig.ApplicationInsightsSamplingSettings, scriptConfig.LogFilter.Filter);

                scriptConfig.HostConfig.LoggerFactory.AddApplicationInsights(clientFactory);
            }
            else
            {
                metricsLogger?.LogEvent(MetricEventNames.ApplicationInsightsDisabled);
            }
        }
        public virtual IEnumerable <ILoggerProvider> CreateLoggerProviders(string hostInstanceId, ScriptHostConfiguration scriptConfig, ScriptSettingsManager settingsManager,
                                                                           Func <bool> isFileLoggingEnabled, Func <bool> isPrimary)
        {
            IList <ILoggerProvider> providers = new List <ILoggerProvider>();

            IMetricsLogger metricsLogger = scriptConfig.HostConfig.GetService <IMetricsLogger>();

            // Automatically register App Insights if the key is present
            if (!string.IsNullOrEmpty(settingsManager?.ApplicationInsightsInstrumentationKey))
            {
                metricsLogger?.LogEvent(MetricEventNames.ApplicationInsightsEnabled);

                ITelemetryClientFactory clientFactory = scriptConfig.HostConfig.GetService <ITelemetryClientFactory>() ??
                                                        new ScriptTelemetryClientFactory(settingsManager.ApplicationInsightsInstrumentationKey, scriptConfig.ApplicationInsightsSamplingSettings, scriptConfig.LogFilter.Filter);

                providers.Add(new ApplicationInsightsLoggerProvider(clientFactory));
            }
            else
            {
                metricsLogger?.LogEvent(MetricEventNames.ApplicationInsightsDisabled);
            }

            providers.Add(new FunctionFileLoggerProvider(hostInstanceId, scriptConfig.RootLogPath, isFileLoggingEnabled, isPrimary));
            providers.Add(new HostFileLoggerProvider(hostInstanceId, scriptConfig.RootLogPath, isFileLoggingEnabled));

            // console logging defaults to false, except for self host
            bool   enableConsole = scriptConfig.IsSelfHost;
            string configValue   = settingsManager.Configuration.GetSection(ScriptConstants.ConsoleLoggingMode).Value;

            if (!string.IsNullOrEmpty(configValue))
            {
                // if it has been explicitly configured that value overrides default
                enableConsole = string.CompareOrdinal(configValue, "always") == 0 ? true : false;
            }
            if (ConsoleLoggingEnabled(scriptConfig, settingsManager))
            {
                providers.Add(new ConsoleLoggerProvider(scriptConfig.LogFilter.Filter, includeScopes: true));
            }

            return(providers);
        }
Exemple #16
0
        /// <summary>
        /// Performs all required initialization on the host.
        /// Must be called before the host is started.
        /// </summary>
        public async Task InitializeAsync(CancellationToken cancellationToken = default)
        {
            _stopwatch.Start();
            using (_metricsLogger.LatencyEvent(MetricEventNames.HostStartupLatency))
            {
                PreInitialize();
                HostInitializing?.Invoke(this, EventArgs.Empty);

                // Generate Functions
                IEnumerable <FunctionMetadata> functionMetadataList = GetFunctionsMetadata();

                _workerRuntime = _workerRuntime ?? Utility.GetWorkerRuntime(functionMetadataList);

                if (!_environment.IsPlaceholderModeEnabled())
                {
                    string runtimeStack = _workerRuntime;

                    // Appending the runtime version is currently only enabled for linux consumption. This will be eventually enabled for
                    // Windows Consumption as well.
                    string runtimeVersion = _environment.GetEnvironmentVariable(RpcWorkerConstants.FunctionWorkerRuntimeVersionSettingName);

                    if (!string.IsNullOrEmpty(runtimeVersion))
                    {
                        runtimeStack = string.Concat(runtimeStack, "-", runtimeVersion);
                    }

                    _metricsLogger.LogEvent(string.Format(MetricEventNames.HostStartupRuntimeLanguage, runtimeStack));
                }

                var directTypes = GetDirectTypes(functionMetadataList);
                await InitializeFunctionDescriptorsAsync(functionMetadataList);

                // Initialize worker function invocation dispatcher only for valid functions after creating function descriptors
                await _functionDispatcher.InitializeAsync(Utility.GetValidFunctions(functionMetadataList, Functions), cancellationToken);

                GenerateFunctions(directTypes);

                CleanupFileSystem();
            }
        }
Exemple #17
0
        internal static object LogInvocationMetrics(IMetricsLogger metrics, FunctionMetadata metadata)
        {
            // log events for each of the binding types used
            foreach (var binding in metadata.Bindings)
            {
                string eventName = binding.IsTrigger ?
                                   string.Format(MetricEventNames.FunctionBindingTypeFormat, binding.Type) :
                                   string.Format(MetricEventNames.FunctionBindingTypeDirectionFormat, binding.Type, binding.Direction);
                metrics.LogEvent(eventName);
            }

            return(metrics.BeginEvent(MetricEventNames.FunctionInvokeLatency, metadata.Name));
        }
        public void Log <TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func <TState, Exception, string> formatter)
        {
            if (!IsEnabled(logLevel))
            {
                return;
            }

            var scope = _scopeProvider.GetScopeDictionary();

            scope.TryGetValue(ScopeKeys.FunctionName, out string functionName);

            _metricsLogger.LogEvent(MetricEventNames.FunctionUserLog, functionName);
        }
        // Called on success and failure
        public void End(bool success)
        {
            startedEvent.Success = success;
            string eventName = success ? MetricEventNames.FunctionInvokeSucceeded : MetricEventNames.FunctionInvokeFailed;

            _metrics.LogEvent(eventName, startedEvent.FunctionName);

            _metrics.EndEvent(startedEvent);

            if (invokeLatencyEvent != null)
            {
                _metrics.EndEvent(invokeLatencyEvent);
            }
        }
Exemple #20
0
        // Called on success and failure
        public void End(bool success)
        {
            _startedEvent.Success = success;

            string eventName    = success ? MetricEventNames.FunctionInvokeSucceeded : MetricEventNames.FunctionInvokeFailed;
            string functionName = _metadata != null ? _metadata.Name : string.Empty;
            string data         = string.Format(Properties.Resources.FunctionInvocationMetricsData, _startedEvent.FunctionMetadata.Language, functionName, success, Stopwatch.IsHighResolution);

            _metrics.LogEvent(eventName, _startedEvent.FunctionName, data);

            _startedEvent.Data = data;
            _metrics.EndEvent(_startedEvent);

            if (_invokeLatencyEvent is MetricEvent metricEvent)
            {
                metricEvent.Data = data;
            }

            _metrics.EndEvent(_invokeLatencyEvent);
        }
        internal static void LogInvocationMetrics(IMetricsLogger metrics, Collection<BindingMetadata> bindings)
        {
            metrics.LogEvent(MetricEventNames.FunctionInvoke);

            // log events for each of the binding types used
            foreach (var binding in bindings)
            {
                string eventName = binding.IsTrigger ?
                    string.Format(MetricEventNames.FunctionBindingTypeFormat, binding.Type) :
                    string.Format(MetricEventNames.FunctionBindingTypeDirectionFormat, binding.Type, binding.Direction);
                metrics.LogEvent(eventName);
            }
        }
Exemple #22
0
 public void LogEvent(MetricEvent metricEvent)
 {
     _metricsLogger.LogEvent(metricEvent);
 }