Skip to content

Commit faca8bc

Browse files
authored
[pack]Use TraceWriter to log startup errors (#5159)
1 parent f0b4858 commit faca8bc

File tree

7 files changed

+210
-125
lines changed

7 files changed

+210
-125
lines changed

src/WebJobs.Script.WebHost/App_Start/WebHostResolver.cs

Lines changed: 86 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -128,69 +128,101 @@ internal void EnsureInitialized(WebHostSettings settings)
128128
// Determine whether we should do normal or standby initialization
129129
if (!WebScriptHostManager.InStandbyMode)
130130
{
131-
// We're not in standby mode. There are two cases to consider:
132-
// 1) We _were_ in standby mode and now we're ready to specialize
133-
// 2) We're doing non-specialization normal initialization
134-
if (_activeHostManager == null &&
135-
(_standbyHostManager == null || (_settingsManager.ContainerReady && _settingsManager.ConfigurationReady)))
136-
{
137-
_specializationTimer?.Dispose();
138-
_specializationTimer = null;
131+
EncureInitializedNonStandbyMode(settings);
132+
}
133+
else
134+
{
135+
EnsureInitializedStandbyMode(settings);
136+
}
137+
}
138+
}
139139

140-
_activeScriptHostConfig = CreateScriptHostConfiguration(settings);
141-
var defaultLoggerFactory = GetDefaultLoggerFactory(settings);
142-
_activeHostManager = new WebScriptHostManager(_activeScriptHostConfig, _secretManagerFactory, _eventManager, _settingsManager, settings, defaultLoggerFactory);
143-
_activeReceiverManager = new WebHookReceiverManager(_activeHostManager.SecretManager);
144-
InitializeFileSystem(_settingsManager.FileSystemIsReadOnly);
140+
private void EnsureInitializedStandbyMode(WebHostSettings settings)
141+
{
142+
try
143+
{
144+
// We're in standby (placeholder) mode. Initialize the standby services.
145+
if (_standbyHostManager == null)
146+
{
147+
var standbySettings = CreateStandbySettings(settings);
148+
_standbyScriptHostConfig = CreateScriptHostConfiguration(standbySettings, true);
149+
var defaultLoggerFactory = GetDefaultLoggerFactory(settings);
150+
151+
_standbyHostManager = new WebScriptHostManager(_standbyScriptHostConfig, _secretManagerFactory, _eventManager, _settingsManager, standbySettings, defaultLoggerFactory);
152+
_standbyReceiverManager = new WebHookReceiverManager(_standbyHostManager.SecretManager);
153+
154+
// TraceWriter is initialized to SystemTraceWriter only after creating WebScriptHostManager
155+
_standbyScriptHostConfig.TraceWriter?.Info("In Standby Mode. Host initializing.");
156+
InitializeFileSystem(_settingsManager.FileSystemIsReadOnly);
157+
StandbyManager.Initialize(_standbyScriptHostConfig);
158+
159+
// start a background timer to identify when specialization happens
160+
// specialization usually happens via an http request (e.g. scale controller
161+
// ping) but this timer is started as well to handle cases where we
162+
// might not receive a request
163+
_specializationTimer = new Timer(OnSpecializationTimerTick, settings, 1000, 1000);
164+
}
165+
}
166+
catch (Exception standbyModeInitEx)
167+
{
168+
_standbyScriptHostConfig?.TraceWriter?.Error("Host failed to initialize in StandbyMode.", standbyModeInitEx);
169+
throw new HostInitializationException("Host failed to initialize in StandbyMode.", standbyModeInitEx);
170+
}
171+
}
145172

146-
if (_standbyHostManager != null)
147-
{
148-
// we're starting the one and only one
149-
// standby mode specialization
150-
_activeScriptHostConfig.TraceWriter.Info(Resources.HostSpecializationTrace);
173+
private void EncureInitializedNonStandbyMode(WebHostSettings settings)
174+
{
175+
try
176+
{
177+
// We're not in standby mode. There are two cases to consider:
178+
// 1) We _were_ in standby mode and now we're ready to specialize
179+
// 2) We're doing non-specialization normal initialization
180+
if (_activeHostManager == null &&
181+
(_standbyHostManager == null || (_settingsManager.ContainerReady && _settingsManager.ConfigurationReady)))
182+
{
183+
_specializationTimer?.Dispose();
184+
_specializationTimer = null;
151185

152-
// After specialization, we need to ensure that custom timezone
153-
// settings configured by the user (WEBSITE_TIME_ZONE) are honored.
154-
// DateTime caches timezone information, so we need to clear the cache.
155-
TimeZoneInfo.ClearCachedData();
186+
_activeScriptHostConfig = CreateScriptHostConfiguration(settings);
187+
var defaultLoggerFactory = GetDefaultLoggerFactory(settings);
188+
_activeHostManager = new WebScriptHostManager(_activeScriptHostConfig, _secretManagerFactory, _eventManager, _settingsManager, settings, defaultLoggerFactory);
189+
_activeReceiverManager = new WebHookReceiverManager(_activeHostManager.SecretManager);
190+
InitializeFileSystem(_settingsManager.FileSystemIsReadOnly);
156191

157-
// ensure we reinitialize hostname after specialization
158-
HostNameProvider.Reset();
159-
}
192+
// TraceWriter is initialized to SystemTraceWriter only after creating WebScriptHostManager
193+
_activeScriptHostConfig.TraceWriter.Info("Host initializing.");
160194

161-
if (_standbyHostManager != null)
162-
{
163-
_standbyHostManager.Stop();
164-
_standbyHostManager.Dispose();
165-
}
166-
_standbyReceiverManager?.Dispose();
167-
_standbyScriptHostConfig = null;
168-
_standbyHostManager = null;
169-
_standbyReceiverManager = null;
195+
if (_standbyHostManager != null)
196+
{
197+
// we're starting the one and only one
198+
// standby mode specialization
199+
_activeScriptHostConfig.TraceWriter.Info(Resources.HostSpecializationTrace);
200+
201+
// After specialization, we need to ensure that custom timezone
202+
// settings configured by the user (WEBSITE_TIME_ZONE) are honored.
203+
// DateTime caches timezone information, so we need to clear the cache.
204+
TimeZoneInfo.ClearCachedData();
205+
206+
// ensure we reinitialize hostname after specialization
207+
HostNameProvider.Reset();
170208
}
171-
}
172-
else
173-
{
174-
// We're in standby (placeholder) mode. Initialize the standby services.
175-
if (_standbyHostManager == null)
209+
210+
if (_standbyHostManager != null)
176211
{
177-
var standbySettings = CreateStandbySettings(settings);
178-
_standbyScriptHostConfig = CreateScriptHostConfiguration(standbySettings, true);
179-
var defaultLoggerFactory = GetDefaultLoggerFactory(settings);
180-
_standbyHostManager = new WebScriptHostManager(_standbyScriptHostConfig, _secretManagerFactory, _eventManager, _settingsManager, standbySettings, defaultLoggerFactory);
181-
_standbyReceiverManager = new WebHookReceiverManager(_standbyHostManager.SecretManager);
182-
183-
InitializeFileSystem(_settingsManager.FileSystemIsReadOnly);
184-
StandbyManager.Initialize(_standbyScriptHostConfig);
185-
186-
// start a background timer to identify when specialization happens
187-
// specialization usually happens via an http request (e.g. scale controller
188-
// ping) but this timer is started as well to handle cases where we
189-
// might not receive a request
190-
_specializationTimer = new Timer(OnSpecializationTimerTick, settings, 1000, 1000);
212+
_standbyHostManager.Stop();
213+
_standbyHostManager.Dispose();
191214
}
215+
_standbyReceiverManager?.Dispose();
216+
_standbyScriptHostConfig = null;
217+
_standbyHostManager = null;
218+
_standbyReceiverManager = null;
192219
}
193220
}
221+
catch (Exception hostInitEx)
222+
{
223+
_activeScriptHostConfig?.TraceWriter?.Error("Host failed to initialize.", hostInitEx);
224+
throw new HostInitializationException("Host failed to initialize.", hostInitEx);
225+
}
194226
}
195227

196228
internal static WebHostSettings CreateStandbySettings(WebHostSettings settings)
@@ -209,7 +241,7 @@ internal static WebHostSettings CreateStandbySettings(WebHostSettings settings)
209241
TraceWriter = settings.TraceWriter,
210242
IsSelfHost = settings.IsSelfHost
211243
};
212-
244+
settings.TraceWriter?.Info("Created Standby WebHostSettings.");
213245
return standbySettings;
214246
}
215247

src/WebJobs.Script.WebHost/WebScriptHostManager.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,7 @@ private async void OnSyncTimerTick(object state)
453453

454454
private void InitializeHttp()
455455
{
456+
_logger.LogDebug("Initializing HttpRequestManager");
456457
// get the registered http configuration from the extension registry
457458
var extensions = Instance.ScriptConfig.HostConfig.GetService<IExtensionRegistry>();
458459
var httpConfig = extensions.GetExtensions<IExtensionConfigProvider>().OfType<HttpExtensionConfiguration>().Single();
@@ -464,10 +465,12 @@ private void InitializeHttp()
464465
// since the request manager is created based on configurable
465466
// settings, it has to be recreated when host config changes
466467
_httpRequestManager = new WebScriptHostRequestManager(httpConfig, PerformanceManager, _metricsLogger, _config.TraceWriter);
468+
_logger.LogDebug("Initialized HttpRequestManager");
467469
}
468470

469471
private void InitializeHttpFunctions(IEnumerable<FunctionDescriptor> functions, HttpExtensionConfiguration httpConfig)
470472
{
473+
_logger.LogDebug("Initializing HttpFunctions");
471474
// we must initialize the route factory here AFTER full configuration
472475
// has been resolved so we apply any route prefix customizations
473476
var functionHttpRouteFactory = new HttpRouteFactory(httpConfig.RoutePrefix);
@@ -486,6 +489,7 @@ private void InitializeHttpFunctions(IEnumerable<FunctionDescriptor> functions,
486489
var httpRouteFactory = function.Metadata.IsProxy ? proxyHttpRouteFactory : functionHttpRouteFactory;
487490
httpRouteFactory.TryAddRoute(_httpRoutes, function);
488491
}
492+
_logger.LogDebug("Initialized HttpFunctions");
489493
}
490494

491495
public override void Shutdown(bool hard = false)
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the MIT License. See License.txt in the project root for license information.
3+
4+
using System;
5+
6+
namespace Microsoft.Azure.WebJobs.Script
7+
{
8+
/// <summary>
9+
/// An exception that indicates an issue initializing a ScriptHost.
10+
/// </summary>
11+
[Serializable]
12+
public class HostInitializationException : Exception
13+
{
14+
public HostInitializationException()
15+
{
16+
}
17+
18+
public HostInitializationException(string message) : base(message)
19+
{
20+
}
21+
22+
public HostInitializationException(string message, Exception inner) : base(message, inner)
23+
{
24+
}
25+
26+
protected HostInitializationException(
27+
System.Runtime.Serialization.SerializationInfo info,
28+
System.Runtime.Serialization.StreamingContext context) : base(info, context)
29+
{
30+
}
31+
}
32+
}

src/WebJobs.Script/WebJobs.Script.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,7 @@
513513
<Compile Include="Description\ScriptFunctionInvokerBase.cs" />
514514
<Compile Include="Description\DotNet\Compilation\FSharp\FSharpCompilation.cs" />
515515
<Compile Include="Diagnostics\LogType.cs" />
516+
<Compile Include="HostInitializationException.cs" />
516517
<Compile Include="Scale\ApplicationPerformanceCounters.cs" />
517518
<Compile Include="Diagnostics\CompositeTraceWriter.cs" />
518519
<Compile Include="Description\Binding\BindingDirection.cs" />

0 commit comments

Comments
 (0)