Skip to content

Commit 9d5193b

Browse files
committed
Add caching to ForwardingLoggerFactory
1 parent da519b6 commit 9d5193b

File tree

2 files changed

+44
-6
lines changed

2 files changed

+44
-6
lines changed

src/WebJobs.Script/Diagnostics/ForwardingLoggerFactory.cs

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
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;
56
using System.Diagnostics;
67
using Microsoft.Azure.WebJobs.Script;
78

@@ -16,8 +17,12 @@ namespace Microsoft.Extensions.Logging
1617
[DebuggerDisplay(@"InnerFactory = \{ {_inner} \}, ScriptHostState = {_manager.State}")]
1718
public sealed class ForwardingLoggerFactory : ILoggerFactory
1819
{
20+
private readonly ConcurrentDictionary<string, ForwardingLogger> _loggers = new(StringComparer.Ordinal);
1921
private readonly ILoggerFactory _inner;
2022
private readonly IScriptHostManager _manager;
23+
private readonly object _sync = new();
24+
25+
private bool _disposed;
2126

2227
public ForwardingLoggerFactory(ILoggerFactory inner, IScriptHostManager manager)
2328
{
@@ -34,12 +39,30 @@ public void AddProvider(ILoggerProvider provider)
3439

3540
/// <inheritdoc />
3641
public ILogger CreateLogger(string categoryName)
37-
=> new ForwardingLogger(categoryName, _inner.CreateLogger(categoryName), _manager);
42+
{
43+
ObjectDisposedException.ThrowIf(_disposed, this);
44+
45+
if (!_loggers.TryGetValue(categoryName, out ForwardingLogger? logger))
46+
{
47+
lock (_sync)
48+
{
49+
if (!_loggers.TryGetValue(categoryName, out logger))
50+
{
51+
ILogger innerLogger = _inner.CreateLogger(categoryName);
52+
logger = new ForwardingLogger(categoryName, innerLogger, _manager);
53+
_loggers[categoryName] = logger;
54+
}
55+
}
56+
}
57+
58+
return logger;
59+
}
3860

3961
/// <inheritdoc />
4062
public void Dispose()
4163
{
42-
// no op.
64+
// this is just to block further logger creation.
65+
_disposed = true;
4366
}
4467
}
4568
}

test/WebJobs.Script.Tests/Diagnostics/ForwardingLoggerFactoryTests.cs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@
33

44
using System;
55
using AwesomeAssertions;
6-
using Microsoft.Extensions.DependencyInjection;
76
using Microsoft.Extensions.Logging;
8-
using Microsoft.Extensions.Logging.Testing;
97
using Moq;
108
using Xunit;
119

@@ -63,9 +61,26 @@ public void CreateLogger_ReturnsLoggerInstance()
6361
}
6462

6563
[Fact]
66-
public void Dispose_DoesNotThrow()
64+
public void CreateLogger_Caching_ReturnsSameInstance()
6765
{
68-
TestHelpers.Act(_factory.Dispose).Should().NotThrow();
66+
string categoryName = "TestCategory";
67+
_mockInnerFactory.Setup(f => f.CreateLogger(categoryName)).Returns(_mockInnerLogger.Object);
68+
69+
ILogger result1 = _factory.CreateLogger(categoryName);
70+
ILogger result2 = _factory.CreateLogger(categoryName);
71+
72+
result1.Should().NotBeNull();
73+
result1.Should().BeOfType<ForwardingLogger>();
74+
result2.Should().BeSameAs(result1);
75+
_mockInnerFactory.Verify(f => f.CreateLogger(categoryName), Times.Once);
76+
}
77+
78+
[Fact]
79+
public void Dispose_BlocksCreation()
80+
{
81+
_factory.Dispose();
82+
TestHelpers.Act(() => _factory.CreateLogger("TestCategory"))
83+
.Should().Throw<ObjectDisposedException>();
6984
}
7085
}
7186
}

0 commit comments

Comments
 (0)