Skip to content

Commit a692ab5

Browse files
[in-proc] Avoid redundant DiagnosticEvents error message (#10396)
1 parent 3b2b683 commit a692ab5

File tree

6 files changed

+38
-22
lines changed

6 files changed

+38
-22
lines changed

src/WebJobs.Script.WebHost/Diagnostics/DiagnosticEventLogger.cs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -54,20 +54,17 @@ private bool IsDiagnosticEvent(IDictionary<string, object> state)
5454

5555
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
5656
{
57-
if (!IsEnabled(logLevel))
57+
// Exit early if logging is not enabled or the state is not a diagnostic event
58+
if (!IsEnabled(logLevel) ||
59+
(_diagnosticEventRepository != null && !_diagnosticEventRepository.IsEnabled()) ||
60+
!(state is IDictionary<string, object> stateInfo && IsDiagnosticEvent(stateInfo)))
5861
{
5962
return;
6063
}
6164

62-
if (state is IDictionary<string, object> stateInfo && IsDiagnosticEvent(stateInfo))
63-
{
64-
string message = formatter(state, exception);
65-
if (_diagnosticEventRepository == null)
66-
{
67-
_diagnosticEventRepository = _diagnosticEventRepositoryFactory.Create();
68-
}
69-
_diagnosticEventRepository.WriteDiagnosticEvent(DateTime.UtcNow, stateInfo[ScriptConstants.ErrorCodeKey].ToString(), logLevel, message, stateInfo[ScriptConstants.HelpLinkKey].ToString(), exception);
70-
}
65+
string message = formatter(state, exception);
66+
_diagnosticEventRepository ??= _diagnosticEventRepositoryFactory.Create();
67+
_diagnosticEventRepository.WriteDiagnosticEvent(DateTime.UtcNow, stateInfo[ScriptConstants.ErrorCodeKey].ToString(), logLevel, message, stateInfo[ScriptConstants.HelpLinkKey].ToString(), exception);
7168
}
7269

7370
public void Dispose()

src/WebJobs.Script.WebHost/Diagnostics/DiagnosticEventNullRepository.cs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,17 @@
22
// Licensed under the MIT License. See License.txt in the project root for license information.
33

44
using System;
5-
using System.Collections.Concurrent;
6-
using System.Threading;
7-
using System.Threading.Tasks;
8-
using Microsoft.Azure.Cosmos.Table;
9-
using Microsoft.Azure.WebJobs.Host.Executors;
10-
using Microsoft.Azure.WebJobs.Script.WebHost.Helpers;
11-
using Microsoft.Extensions.Configuration;
125
using Microsoft.Extensions.Logging;
136

147
namespace Microsoft.Azure.WebJobs.Script.WebHost.Diagnostics
158
{
169
public class DiagnosticEventNullRepository : IDiagnosticEventRepository
1710
{
1811
public void WriteDiagnosticEvent(DateTime timestamp, string errorCode, LogLevel level, string message, string helpLink, Exception exception) { }
12+
13+
public bool IsEnabled()
14+
{
15+
return false;
16+
}
1917
}
2018
}

src/WebJobs.Script.WebHost/Diagnostics/DiagnosticEventTableStorageRepository.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ public class DiagnosticEventTableStorageRepository : IDiagnosticEventRepository,
3939
private bool _disposed = false;
4040
private bool _purged = false;
4141
private string _tableName;
42+
private bool _isEnabled = true;
4243

4344
internal DiagnosticEventTableStorageRepository(IConfiguration configuration, IHostIdProvider hostIdProvider, IEnvironment environment, IScriptHostManager scriptHostManager,
4445
ILogger<DiagnosticEventTableStorageRepository> logger, int logFlushInterval)
@@ -66,10 +67,16 @@ internal TableServiceClient TableClient
6667
try
6768
{
6869
_tableClient = new TableServiceClient(storageConnectionString);
70+
71+
// The TableServiceClient only verifies the format of the connection string.
72+
// To ensure the storage account exists and supports Table storage, validate the connection string by retrieving the properties of the table service.
73+
_ = _tableClient.GetProperties();
6974
}
7075
catch (Exception ex)
7176
{
72-
_logger.LogError(ex, "Azure Storage connection string is empty or invalid. Unable to write diagnostic events.");
77+
_logger.LogError(ex, "The Azure Storage connection string is either empty or invalid. Unable to record diagnostic events, so the diagnostic logging service is being stopped.");
78+
_isEnabled = false;
79+
StopTimer();
7380
}
7481
}
7582

@@ -269,6 +276,11 @@ public void WriteDiagnosticEvent(DateTime timestamp, string errorCode, LogLevel
269276
}
270277
}
271278

279+
public bool IsEnabled()
280+
{
281+
return _isEnabled;
282+
}
283+
272284
private bool IsPrimaryHost()
273285
{
274286
var primaryHostStateProvider = _serviceProvider?.GetService<IPrimaryHostStateProvider>();

src/WebJobs.Script.WebHost/Diagnostics/IDiagnosticEventRepository.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22
// Licensed under the MIT License. See License.txt in the project root for license information.
33

44
using System;
5-
using System.Collections.Generic;
6-
using System.Threading.Tasks;
75
using Microsoft.Extensions.Logging;
86

97
namespace Microsoft.Azure.WebJobs.Script.WebHost.Diagnostics
108
{
119
public interface IDiagnosticEventRepository
1210
{
1311
void WriteDiagnosticEvent(DateTime timestamp, string errorCode, LogLevel level, string message, string helpLink, Exception exception);
12+
13+
bool IsEnabled();
1414
}
1515
}

test/WebJobs.Script.Tests.Integration/Diagnostics/DiagnosticEventTableStorageRepositoryTests.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,11 +153,15 @@ public void GetDiagnosticEventsTable_LogsError_StorageConnectionStringIsNotPrese
153153
var configuration = new ConfigurationBuilder().Build();
154154
DiagnosticEventTableStorageRepository repository =
155155
new DiagnosticEventTableStorageRepository(configuration, _hostIdProvider, testEnvironment, _scriptHostMock.Object, _logger);
156+
157+
// The repository should be initially enabled and then disabled after TableServiceClient failure.
158+
Assert.True(repository.IsEnabled());
156159
DateTime dateTime = new DateTime(2021, 1, 1);
157160
var cloudTable = repository.GetDiagnosticEventsTable(dateTime);
158161
Assert.Null(cloudTable);
159162
var messages = _loggerProvider.GetAllLogMessages();
160-
Assert.Equal(messages[0].FormattedMessage, "Azure Storage connection string is empty or invalid. Unable to write diagnostic events.");
163+
Assert.Equal(messages[0].FormattedMessage, "The Azure Storage connection string is either empty or invalid. Unable to record diagnostic events, so the diagnostic logging service is being stopped.");
164+
Assert.False(repository.IsEnabled());
161165
}
162166

163167
[Fact]
@@ -274,7 +278,7 @@ public async Task FlushLogs_LogsErrorAndClearsEvents_WhenTableCreatingFails()
274278
var logMessage = _loggerProvider.GetAllLogMessages().SingleOrDefault(m => m.FormattedMessage.Contains("Unable to get table reference"));
275279
Assert.NotNull(logMessage);
276280

277-
var messagePresent = _loggerProvider.GetAllLogMessages().Any(m => m.FormattedMessage.Contains("Azure Storage connection string is empty or invalid. Unable to write diagnostic events."));
281+
var messagePresent = _loggerProvider.GetAllLogMessages().Any(m => m.FormattedMessage.Contains("The Azure Storage connection string is either empty or invalid. Unable to record diagnostic events, so the diagnostic logging service is being stopped."));
278282
Assert.True(messagePresent);
279283

280284
Assert.Equal(0, repository.Events.Values.Count());

test/WebJobs.Script.Tests.Shared/TestDiagnosticEventRepository.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,9 @@ public void FlushLogs()
3535
{
3636
Events.Clear();
3737
}
38+
39+
public bool IsEnabled()
40+
{
41+
return true;
42+
}
3843
}

0 commit comments

Comments
 (0)