|
4 | 4 | using System;
|
5 | 5 | using System.Collections.Generic;
|
6 | 6 | using System.Linq;
|
7 |
| -using System.Threading.Tasks; |
8 | 7 | using Microsoft.Extensions.Compliance.Testing;
|
9 | 8 | using Microsoft.Extensions.DependencyInjection;
|
10 | 9 | using Microsoft.Extensions.Diagnostics.Enrichment;
|
|
14 | 13 | using Moq;
|
15 | 14 | using Xunit;
|
16 | 15 | #if NET9_0_OR_GREATER
|
| 16 | +using System.Threading.Tasks; |
17 | 17 | using Microsoft.Extensions.Diagnostics.Buffering;
|
18 | 18 | #endif
|
19 | 19 |
|
20 | 20 | namespace Microsoft.Extensions.Logging.Test;
|
21 | 21 |
|
22 |
| -public class ExtendedLoggerTests |
| 22 | +public static class ExtendedLoggerTests |
23 | 23 | {
|
24 | 24 | [Theory]
|
25 | 25 | [CombinatorialData]
|
@@ -156,113 +156,6 @@ public static void Sampling()
|
156 | 156 | Assert.Equal(0, provider.Logger!.Collector.Count);
|
157 | 157 | }
|
158 | 158 |
|
159 |
| -#if NET9_0_OR_GREATER |
160 |
| - [Fact] |
161 |
| - public static void GlobalBuffering_CanonicalUsecase() |
162 |
| - { |
163 |
| - using var provider = new Provider(); |
164 |
| - using ILoggerFactory factory = Utils.CreateLoggerFactory( |
165 |
| - builder => |
166 |
| - { |
167 |
| - builder.AddProvider(provider); |
168 |
| - builder.AddGlobalBuffer(LogLevel.Warning); |
169 |
| - }); |
170 |
| - |
171 |
| - ILogger logger = factory.CreateLogger("my category"); |
172 |
| - logger.LogWarning("MSG0"); |
173 |
| - logger.Log(LogLevel.Warning, new EventId(2, "ID2"), "some state", null, (_, _) => "MSG2"); |
174 |
| - |
175 |
| - // nothing is logged because the buffer not flushed yet |
176 |
| - Assert.Equal(0, provider.Logger!.Collector.Count); |
177 |
| - |
178 |
| - // instead of this, users would get LogBuffer from DI and call Flush on it |
179 |
| - Utils.DisposingLoggerFactory dlf = (Utils.DisposingLoggerFactory)factory; |
180 |
| - GlobalLogBuffer buffer = dlf.ServiceProvider.GetRequiredService<GlobalLogBuffer>(); |
181 |
| - |
182 |
| - buffer.Flush(); |
183 |
| - |
184 |
| - // 2 log records emitted because the buffer has been flushed |
185 |
| - Assert.Equal(2, provider.Logger!.Collector.Count); |
186 |
| - } |
187 |
| - |
188 |
| - [Fact] |
189 |
| - public static void GlobalBuffering_ParallelLogging() |
190 |
| - { |
191 |
| - using var provider = new Provider(); |
192 |
| - using ILoggerFactory factory = Utils.CreateLoggerFactory( |
193 |
| - builder => |
194 |
| - { |
195 |
| - builder.AddProvider(provider); |
196 |
| - builder.AddGlobalBuffer(LogLevel.Warning); |
197 |
| - }); |
198 |
| - |
199 |
| - ILogger logger = factory.CreateLogger("my category"); |
200 |
| - |
201 |
| - // 1000 threads logging at the same time |
202 |
| - Parallel.For(0, 1000, _ => |
203 |
| - { |
204 |
| - logger.LogWarning("MSG0"); |
205 |
| - logger.Log(LogLevel.Warning, new EventId(2, "ID2"), "some state", null, (_, _) => "MSG2"); |
206 |
| - }); |
207 |
| - |
208 |
| - // nothing is logged because the buffer not flushed yet |
209 |
| - Assert.Equal(0, provider.Logger!.Collector.Count); |
210 |
| - |
211 |
| - |
212 |
| - Utils.DisposingLoggerFactory dlf = (Utils.DisposingLoggerFactory)factory; |
213 |
| - GlobalLogBuffer buffer = dlf.ServiceProvider.GetRequiredService<GlobalLogBuffer>(); |
214 |
| - |
215 |
| - buffer.Flush(); |
216 |
| - |
217 |
| - // 2000 log records emitted because the buffer has been flushed |
218 |
| - Assert.Equal(2000, provider.Logger!.Collector.Count); |
219 |
| - } |
220 |
| - |
221 |
| - [Fact] |
222 |
| - public async Task GlobalBuffering_ParallelLoggingAndFlushing() |
223 |
| - { |
224 |
| - // Arrange |
225 |
| - using var provider = new Provider(); |
226 |
| - using ILoggerFactory factory = Utils.CreateLoggerFactory( |
227 |
| - builder => |
228 |
| - { |
229 |
| - builder.AddProvider(provider); |
230 |
| - builder.AddGlobalBuffer(options => |
231 |
| - { |
232 |
| - options.AutoFlushDuration = TimeSpan.Zero; |
233 |
| - options.Rules.Add(new LogBufferingFilterRule(logLevel: LogLevel.Warning)); |
234 |
| - }); |
235 |
| - }); |
236 |
| - |
237 |
| - ILogger logger = factory.CreateLogger("my category"); |
238 |
| - Utils.DisposingLoggerFactory dlf = (Utils.DisposingLoggerFactory)factory; |
239 |
| - GlobalLogBuffer buffer = dlf.ServiceProvider.GetRequiredService<GlobalLogBuffer>(); |
240 |
| - |
241 |
| - // Act - Run logging and flushing operations in parallel |
242 |
| - await Task.Run(() => |
243 |
| - { |
244 |
| - Parallel.For(0, 100, i => |
245 |
| - { |
246 |
| - logger.LogWarning("MSG0"); |
247 |
| - logger.LogWarning("MSG1"); |
248 |
| - logger.LogWarning("MSG2"); |
249 |
| - logger.LogWarning("MSG3"); |
250 |
| - logger.LogWarning("MSG4"); |
251 |
| - logger.LogWarning("MSG5"); |
252 |
| - logger.LogWarning("MSG6"); |
253 |
| - logger.LogWarning("MSG7"); |
254 |
| - logger.LogWarning("MSG8"); |
255 |
| - logger.LogWarning("MSG9"); |
256 |
| - buffer.Flush(); |
257 |
| - }); |
258 |
| - }); |
259 |
| - |
260 |
| - buffer.Flush(); |
261 |
| - Assert.Equal(1000, provider.Logger!.Collector.Count); |
262 |
| - } |
263 |
| - |
264 |
| -#endif |
265 |
| - |
266 | 159 | [Theory]
|
267 | 160 | [CombinatorialData]
|
268 | 161 | public static void BagAndJoiner(bool objectVersion)
|
@@ -1026,6 +919,112 @@ public static void LegacyLogging_OriginalFormatMustBeLastInTheListOfStatePropert
|
1026 | 919 | Assert.Equal("V4", property.Value);
|
1027 | 920 | }
|
1028 | 921 |
|
| 922 | +#if NET9_0_OR_GREATER |
| 923 | + [Fact] |
| 924 | + public static void GlobalBuffering_CanonicalUsecase() |
| 925 | + { |
| 926 | + using var provider = new Provider(); |
| 927 | + using ILoggerFactory factory = Utils.CreateLoggerFactory( |
| 928 | + builder => |
| 929 | + { |
| 930 | + builder.AddProvider(provider); |
| 931 | + builder.AddGlobalBuffer(LogLevel.Warning); |
| 932 | + }); |
| 933 | + |
| 934 | + ILogger logger = factory.CreateLogger("my category"); |
| 935 | + logger.LogWarning("MSG0"); |
| 936 | + logger.Log(LogLevel.Warning, new EventId(2, "ID2"), "some state", null, (_, _) => "MSG2"); |
| 937 | + |
| 938 | + // nothing is logged because the buffer not flushed yet |
| 939 | + Assert.Equal(0, provider.Logger!.Collector.Count); |
| 940 | + |
| 941 | + // instead of this, users would get LogBuffer from DI and call Flush on it |
| 942 | + Utils.DisposingLoggerFactory dlf = (Utils.DisposingLoggerFactory)factory; |
| 943 | + GlobalLogBuffer buffer = dlf.ServiceProvider.GetRequiredService<GlobalLogBuffer>(); |
| 944 | + |
| 945 | + buffer.Flush(); |
| 946 | + |
| 947 | + // 2 log records emitted because the buffer has been flushed |
| 948 | + Assert.Equal(2, provider.Logger!.Collector.Count); |
| 949 | + } |
| 950 | + |
| 951 | + [Fact] |
| 952 | + public static void GlobalBuffering_ParallelLogging() |
| 953 | + { |
| 954 | + using var provider = new Provider(); |
| 955 | + using ILoggerFactory factory = Utils.CreateLoggerFactory( |
| 956 | + builder => |
| 957 | + { |
| 958 | + builder.AddProvider(provider); |
| 959 | + builder.AddGlobalBuffer(LogLevel.Warning); |
| 960 | + }); |
| 961 | + |
| 962 | + ILogger logger = factory.CreateLogger("my category"); |
| 963 | + |
| 964 | + // 1000 threads logging at the same time |
| 965 | + Parallel.For(0, 1000, _ => |
| 966 | + { |
| 967 | + logger.LogWarning("MSG0"); |
| 968 | + logger.Log(LogLevel.Warning, new EventId(2, "ID2"), "some state", null, (_, _) => "MSG2"); |
| 969 | + }); |
| 970 | + |
| 971 | + // nothing is logged because the buffer not flushed yet |
| 972 | + Assert.Equal(0, provider.Logger!.Collector.Count); |
| 973 | + |
| 974 | + Utils.DisposingLoggerFactory dlf = (Utils.DisposingLoggerFactory)factory; |
| 975 | + GlobalLogBuffer buffer = dlf.ServiceProvider.GetRequiredService<GlobalLogBuffer>(); |
| 976 | + |
| 977 | + buffer.Flush(); |
| 978 | + |
| 979 | + // 2000 log records emitted because the buffer has been flushed |
| 980 | + Assert.Equal(2000, provider.Logger!.Collector.Count); |
| 981 | + } |
| 982 | + |
| 983 | + [Fact] |
| 984 | + public static async Task GlobalBuffering_ParallelLoggingAndFlushing() |
| 985 | + { |
| 986 | + // Arrange |
| 987 | + using var provider = new Provider(); |
| 988 | + using ILoggerFactory factory = Utils.CreateLoggerFactory( |
| 989 | + builder => |
| 990 | + { |
| 991 | + builder.AddProvider(provider); |
| 992 | + builder.AddGlobalBuffer(options => |
| 993 | + { |
| 994 | + options.AutoFlushDuration = TimeSpan.Zero; |
| 995 | + options.Rules.Add(new LogBufferingFilterRule(logLevel: LogLevel.Warning)); |
| 996 | + }); |
| 997 | + }); |
| 998 | + |
| 999 | + ILogger logger = factory.CreateLogger("my category"); |
| 1000 | + Utils.DisposingLoggerFactory dlf = (Utils.DisposingLoggerFactory)factory; |
| 1001 | + GlobalLogBuffer buffer = dlf.ServiceProvider.GetRequiredService<GlobalLogBuffer>(); |
| 1002 | + |
| 1003 | + // Act - Run logging and flushing operations in parallel |
| 1004 | + await Task.Run(() => |
| 1005 | + { |
| 1006 | + Parallel.For(0, 100, i => |
| 1007 | + { |
| 1008 | + logger.LogWarning("MSG0"); |
| 1009 | + logger.LogWarning("MSG1"); |
| 1010 | + logger.LogWarning("MSG2"); |
| 1011 | + logger.LogWarning("MSG3"); |
| 1012 | + logger.LogWarning("MSG4"); |
| 1013 | + logger.LogWarning("MSG5"); |
| 1014 | + logger.LogWarning("MSG6"); |
| 1015 | + logger.LogWarning("MSG7"); |
| 1016 | + logger.LogWarning("MSG8"); |
| 1017 | + logger.LogWarning("MSG9"); |
| 1018 | + buffer.Flush(); |
| 1019 | + }); |
| 1020 | + }); |
| 1021 | + |
| 1022 | + buffer.Flush(); |
| 1023 | + Assert.Equal(1000, provider.Logger!.Collector.Count); |
| 1024 | + } |
| 1025 | + |
| 1026 | +#endif |
| 1027 | + |
1029 | 1028 | private sealed class CustomLoggerProvider : ILoggerProvider
|
1030 | 1029 | {
|
1031 | 1030 | private readonly string _providerName;
|
|
0 commit comments