private static NLogLoggerProvider CreateNLogLoggerProvider(IServiceProvider serviceProvider, IConfiguration configuration, NLogAspNetCoreOptions options, NLog.LogFactory logFactory) { configuration = SetupConfiguration(serviceProvider, configuration); NLogLoggerProvider provider = new NLogLoggerProvider(options ?? NLogAspNetCoreOptions.Default, logFactory ?? LogManager.LogFactory); if (configuration != null && options == null) { provider.Configure(configuration.GetSection("Logging:NLog")); } return(provider); }
private static NLogLoggerProvider CreateNLogLoggerProvider(IServiceProvider serviceProvider, IConfiguration configuration, NLogProviderOptions options) { configuration = SetupConfiguration(serviceProvider, configuration); NLogLoggerProvider provider = new NLogLoggerProvider(options); if (configuration != null && options == null) { provider.Configure(configuration.GetSection("Logging:NLog")); } return(provider); }
/// <summary> /// Enable NLog as logging provider in ASP.NET Core. /// </summary> /// <param name="factory"></param> /// <returns></returns> public static ILoggerFactory AddNLog(this ILoggerFactory factory) { //ignore this //LogManager.AddHiddenAssembly(typeof(AspNetExtensions).GetTypeInfo().Assembly); using (var provider = new NLogLoggerProvider()) { factory.AddProvider(provider); } return(factory); }
/// <summary> /// 添加NLog日志记录器 /// </summary> /// <param name="factory">日志工厂</param> /// <param name="fileName">配置文件名称</param> public static ILoggerFactory AddNLog(this ILoggerFactory factory, string fileName = InternalConst.DefaultConfigFile) { if (!string.IsNullOrEmpty(fileName) && File.Exists(fileName)) { LogManager.Configuration = new XmlLoggingConfiguration(fileName, true); } LogManager.AddHiddenAssembly(typeof(NLogLoggerFactoryExtensions).GetTypeInfo().Assembly); using (var provider = new NLogLoggerProvider()) factory.AddProvider(provider); return(factory); }
/// <summary> /// Configure services. /// </summary> private void ConfigureServices(IServiceCollection services) { NLogLoggerProvider provider = new NLogLoggerProvider(); services.AddLogging(builder => { builder.SetMinimumLevel(LogLevel.Trace); builder.AddConsole(); builder.AddDebug(); builder.AddProvider(new NLogLoggerProvider()); }); }
private static NLogLoggerProvider CreateNLogLoggerProvider(IServiceProvider serviceProvider, IConfiguration configuration, NLogProviderOptions options) { NLogLoggerProvider provider = new NLogLoggerProvider(options); if (configuration != null) { ConfigSettingLayoutRenderer.DefaultConfiguration = configuration; if (options == null) { provider.Configure(configuration.GetSection("Logging:NLog")); } } return(provider); }
private static void InitializeDatabaseFactory() { LoggingConfiguration factoryConfiguration = new LoggingConfiguration(); // All messages from Trace to Warn levels write to the general file FileTarget fileTarget_DatabaseGeneral = new FileTarget() { Name = $"{Constants.ApplicationNameFormatted}Database", FileName = Path.Combine(Constants.LogDirectory, "Database.General.log"), Layout = "${longdate} [${pad:padCharacter= :padding=5:fixedLength=true:alignmentOnTruncation=Right:${uppercase:${level}}}] [${callsite:includeNamespace=false:cleanNamesOfAnonymousDelegates=true:cleanNamesOfAsyncContinuations=true}] ${message}", ArchiveFileName = Path.Combine(Constants.LogDirectory, "Database.General{#}.Archive.log"), ArchiveEvery = FileArchivePeriod.Day, ArchiveNumbering = ArchiveNumberingMode.Rolling, MaxArchiveFiles = 7, ConcurrentWrites = false }; // Limit how often the file will get written to disk. // Default: BufferSize = 50 (log events), FlushTimeout = 5000 (milliseconds) BufferingTargetWrapper fileAsyncTargetWrapper_DatabaseGeneral = new BufferingTargetWrapper { Name = $"{Constants.ApplicationNameFormatted}Database", WrappedTarget = fileTarget_DatabaseGeneral, BufferSize = 75, FlushTimeout = 5000, SlidingTimeout = false }; factoryConfiguration.AddTarget(fileAsyncTargetWrapper_DatabaseGeneral); factoryConfiguration.AddRule(LogLevel.Info, LogLevel.Warn, $"{Constants.ApplicationNameFormatted}Database"); // All messages from Warn to Fatal levels write to the error file with advanced trace information FileTarget fileTarget_DatabaseError = new FileTarget() { Name = $"{Constants.ApplicationNameFormatted}Database", FileName = Path.Combine(Constants.LogDirectory, "Database.Error.log"), Layout = "${longdate} [${pad:padCharacter= :padding=5:fixedLength=true:alignmentOnTruncation=Right:${uppercase:${level}}}] [${callsite:includeSourcePath=true:cleanNamesOfAnonymousDelegates=true:cleanNamesOfAsyncContinuations=true}:${callsite-linenumber}; ${stacktrace}] ${message}${exception:format=ToString,StackTrace}", ArchiveFileName = Path.Combine(Constants.LogDirectory, "Database.Error{#}.Archive.log"), ArchiveEvery = FileArchivePeriod.Day, ArchiveNumbering = ArchiveNumberingMode.Rolling, MaxArchiveFiles = 7, ConcurrentWrites = false }; factoryConfiguration.AddTarget(fileTarget_DatabaseError); factoryConfiguration.AddRule(LogLevel.Error, LogLevel.Fatal, $"{Constants.ApplicationNameFormatted}Database"); _DatabaseFactoryNLog = new LogFactory(factoryConfiguration); NLogLoggerProvider loggerProvider = new NLogLoggerProvider(new NLogProviderOptions(), _DatabaseFactoryNLog); DatabaseFactory = new MSLogging.LoggerFactory(new[] { loggerProvider }); }
public void CreateLogger_HappyPath_LoggerWithCorrectName() { // Arrange var unitUnderTest = new NLogLoggerProvider(); string name = "namespace.class1"; // Act var result = unitUnderTest.CreateLogger(name); // Assert Assert.NotNull(result); var logger = Assert.IsType <NLogLogger>(result); Assert.Equal(name, logger.LoggerName); }
public void CreateAnyLogger() { LoggerFactory factory = new LoggerFactory(); NLogLoggerSettings nLogLoggerSettings = new NLogLoggerSettings { }; NLogLoggerProvider nLogLoggerProvider = new NLogLoggerProvider(nLogLoggerSettings); factory.AddProvider(nLogLoggerProvider); // Create fake logger ILogger logger = factory.CreateLogger("Fake"); Assert.AreEqual(1, nLogLoggerProvider.NLogLoggers.Count); }
public void Dispose_HappyPath_FlushLogFactory() { // Arrange var provider = new NLogLoggerProvider(); var internalLogWriter = CaptureInternalLog(); // Act provider.Dispose(); // Assert var internalLog = internalLogWriter.ToString(); Assert.Contains("LogFactory.Flush", internalLog, StringComparison.OrdinalIgnoreCase); }
public void CreateAnyLogger() { LoggerFactory factory = new LoggerFactory(); NLogLoggerSettings nLogLoggerSettings = new NLogLoggerSettings { }; NLogLoggerProvider nLogLoggerProvider = new NLogLoggerProvider(nLogLoggerSettings); factory.AddProvider(nLogLoggerProvider); // Create logger with any category name logger ILogger logger = factory.CreateLogger("Fake"); Assert.AreEqual(1, nLogLoggerProvider.NLogLoggers.Count); Assert.IsTrue(nLogLoggerProvider.NLogLoggers["Fake"].TryGetTarget(out NLogLogger nLogLogger)); }
public void AddProvider_StateUnderTest_ExpectedBehavior() { // Arrange var unitUnderTest = new NLogLoggerFactory(); ILoggerProvider provider = new NLogLoggerProvider(); var internalLogWriter = CaptureInternalLog(); // Act unitUnderTest.AddProvider(provider); // Assert var internalLog = internalLogWriter.ToString(); Assert.Contains("AddProvider will be ignored", internalLog, StringComparison.OrdinalIgnoreCase); }
public void Dispose_HappyPath_FlushLogFactory() { // Arrange var logFactory = new LogFactory(); var logConfig = new Config.LoggingConfiguration(logFactory); logConfig.AddTarget(new Targets.MemoryTarget("output")); logConfig.AddRuleForAllLevels(new Targets.Wrappers.BufferingTargetWrapper("buffer", logConfig.FindTargetByName("output"))); logFactory.Configuration = logConfig; var provider = new NLogLoggerProvider(null, logFactory); // Act provider.CreateLogger("test").LogInformation("Hello"); provider.Dispose(); // Assert Assert.Single(logFactory.Configuration.FindTargetByName <Targets.MemoryTarget>("output").Logs); }
private static NLogLoggerProvider CreateNLogLoggerProvider(IServiceProvider serviceProvider, IConfiguration configuration, NLogAspNetCoreOptions options, NLog.LogFactory logFactory) { configuration = SetupConfiguration(serviceProvider, configuration); NLogLoggerProvider provider = new NLogLoggerProvider(options ?? NLogAspNetCoreOptions.Default, logFactory ?? LogManager.LogFactory); if (configuration != null) { provider.Configure(configuration.GetSection("Logging:NLog")); TryLoadConfigurationFromSection(provider, configuration); } if (provider.Options.ShutdownOnDispose) { provider.LogFactory.AutoShutdown = false; } return(provider); }
protected NLogLoggerProvider ConfigureLoggerProvider(NLogProviderOptions options = null, Action <ServiceCollection> configureServices = null) { if (_serviceProvider == null) { var logFactory = new LogFactory(); LoggerProvider = new NLogLoggerProvider(options ?? new NLogProviderOptions { CaptureMessageTemplates = true, CaptureMessageProperties = true }, logFactory); var services = new ServiceCollection(); services.AddSingleton <ILoggerFactory, LoggerFactory>(); services.AddSingleton(typeof(ILogger <>), typeof(Logger <>)); configureServices?.Invoke(services); _serviceProvider = services.BuildServiceProvider(); var loggerFactory = _serviceProvider.GetRequiredService <ILoggerFactory>(); loggerFactory.AddProvider(LoggerProvider); } return(LoggerProvider); }
public void CreateNullLogger() { LoggerFactory factory = new LoggerFactory(); NLogLoggerSettings nLogLoggerSettings = new NLogLoggerSettings { AcceptedCategoryNames = new System.Collections.Generic.List <string> { nameof(NLogLoggerTest) } }; NLogLoggerProvider nLogLoggerProvider = new NLogLoggerProvider(nLogLoggerSettings); factory.AddProvider(nLogLoggerProvider); // Create fake logger ILogger logger = factory.CreateLogger("Fake"); Assert.AreEqual(0, nLogLoggerProvider.NLogLoggers.Count); }
public static void Main(string[] args) { var provider = new NLogLoggerProvider(); // Add it before initializing the Cluster Cassandra.Diagnostics.AddLoggerProvider(provider); Cluster cluster = Cluster.Builder(). AddContactPoint("127.0.0.1"). Build(); ISession session = null; try { session = cluster.Connect(); } catch (Exception) { } }
public static ILoggerFactory AddNLog(this ILoggerFactory factory, IConfigurationRoot configuration) { //ignore this LogManager.AddHiddenAssembly(typeof(AspNetExtensions).GetTypeInfo().Assembly); using (var provider = new NLogLoggerProvider()) { factory.AddProvider(provider); } var configFilePath = configuration[NLogPathKey]; if (string.IsNullOrEmpty(configFilePath)) { throw new NLogConfigurationException("Not found NLog config path. Did you add NLog config?"); } ConfigureNLog(configFilePath); return(factory); }
public void AddProvider_StateUnderTest_ExpectedBehavior() { // Arrange var logFactory = new LogFactory(); var logConfig = new Config.LoggingConfiguration(logFactory); logConfig.AddRuleForAllLevels(new Targets.MemoryTarget("output")); logFactory.Configuration = logConfig; var provider = new NLogLoggerProvider(null, logFactory); var loggerFactory = new NLogLoggerFactory(provider); // Act ILoggerProvider newProvider = new NLogLoggerProvider(); loggerFactory.AddProvider(newProvider); loggerFactory.CreateLogger("test").LogInformation("Hello"); // Assert Assert.Single(logFactory.Configuration.FindTargetByName <Targets.MemoryTarget>("output").Logs); }
public static (ILoggerProvider LogggerProvider, LogFactory LogFactory) CreateNLogProvider() { LoggingConfiguration Config = new LoggingConfiguration(); JsonLayout Layout = new JsonLayout { IncludeAllProperties = true }; Layout.Attributes.Add(new JsonAttribute("time", "${longdate}")); Layout.Attributes.Add(new JsonAttribute("threadId", "${threadid}")); Layout.Attributes.Add(new JsonAttribute("level", "${level:upperCase=true}")); Layout.Attributes.Add(new JsonAttribute("message", "${message}")); Target Target = new FileTarget("File") { FileName = $"{LogFileDirectoryPath}Log${{shortdate}}.log", Layout = Layout, KeepFileOpen = true, // Default for Serilog, but not for NLog ConcurrentWrites = false, // Matches Serilog Shared AutoFlush = true, // Matches Serilog Buffered ArchiveEvery = FileArchivePeriod.Day, ArchiveAboveSize = ProviderComparisonBenchmarks.LogFileMaxSizeInBytes, ArchiveNumbering = ArchiveNumberingMode.Sequence, }; Config.AddTarget("File", Target); Config.AddRuleForAllLevels(Target, "*", true); LogFactory LogFactory = new LogFactory(Config); NLogLoggerProvider Provider = new NLogLoggerProvider( new NLogProviderOptions { ShutdownOnDispose = true }, LogFactory); return(Provider, LogFactory); }
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory) { var logProvider = new NLogLoggerProvider(); try { loggerFactory.AddConsole(); loggerFactory.AddDebug(LogLevel.Information); loggerFactory?.AddProvider(logProvider); app.UseMvc(); var options = new DefaultFilesOptions(); options.DefaultFileNames.Clear(); options.DefaultFileNames.Add("default.htm"); app.UseDefaultFiles(options); app.UseStaticFiles(); } finally { logProvider.Dispose(); } }
public void CreateAnyLoggerStartsAndEndsWith() { LoggerFactory factory = new LoggerFactory(); NLogLoggerSettings nLogLoggerSettings = new NLogLoggerSettings { }; nLogLoggerSettings.AcceptedCategoryNames = new List <string> { "f*", "*name" }; NLogLoggerProvider nLogLoggerProvider = new NLogLoggerProvider(nLogLoggerSettings); var logger = nLogLoggerProvider.CreateLogger("fAbracadabra") as NLogLogger; Assert.IsInstanceOfType(logger, typeof(NLogLogger)); Assert.AreEqual("fAbracadabra", logger.CategoryName); logger = nLogLoggerProvider.CreateLogger("RoundNAmE") as NLogLogger; Assert.IsInstanceOfType(logger, typeof(NLogLogger)); Assert.AreEqual("RoundNAmE", logger.CategoryName); }
public void CreateAnyLoggerWithAlias() { LoggerFactory factory = new LoggerFactory(); NLogLoggerSettings nLogLoggerSettings = new NLogLoggerSettings { }; nLogLoggerSettings.AcceptedAliasesCategoryNames = new Dictionary <string, string> { { "f*", "Remap1" }, { "*name", "Remap2" } }; NLogLoggerProvider nLogLoggerProvider = new NLogLoggerProvider(nLogLoggerSettings); var logger = nLogLoggerProvider.CreateLogger("fAbracadabra") as NLogLogger; Assert.IsInstanceOfType(logger, typeof(NLogLogger)); Assert.AreEqual("Remap1", logger.CategoryName); logger = nLogLoggerProvider.CreateLogger("RoundNAmE") as NLogLogger; Assert.IsInstanceOfType(logger, typeof(NLogLogger)); Assert.AreEqual("Remap2", logger.CategoryName); }
static public void Main() { AllocConsole(); ILogger logger = new NLogLoggerProvider().CreateLogger(nameof(DropAssets)); using (_game = new GlyphGame(logger, x => _rawContentLibrary = new RawContentLibrary(x, logger, ContentPath, CachePath))) { _form = (Form)Control.FromHandle(_game.Window.Handle); _form.AllowDrop = true; _form.DragOver += OnDragOver; _form.DragDrop += OnDragDrop; GlyphEngine engine = _game.Engine; GlyphObject root = engine.Root; root.Add <SceneNode>(); engine.InteractionManager.Root.Add(root.Add <InteractiveRoot>().Interactive); var freeCamera = root.Add <FreeCamera>(); freeCamera.View = engine.RootView; freeCamera.Client = _game; var scene = root.Add <GlyphObject>(); scene.Add <SceneNode>().RootNode(); _spriteLoader = scene.Add <SpriteLoader>(); scene.Add <SpriteRenderer>(); _soundLoader = scene.Add <SoundLoader>(); _soundEmitter = scene.Add <SoundEmitter>(); scene.Add <SoundListener>(); _songPlayer = scene.Add <SongPlayer>(); _game.Run(); } }
public void CreateMemoryLogger() { LoggerFactory factory = new LoggerFactory(); string category = String.Empty; LogLevel logLevel = LogLevel.None; NLogLoggerSettings nLogLoggerSettings = new NLogLoggerSettings { AcceptedCategoryNames = new System.Collections.Generic.List <string> { nameof(NLogLoggerTest) }, Filter = (s, l) => { category = s; logLevel = l; return(true); } }; NLogLoggerProvider nLogLoggerProvider = new NLogLoggerProvider(nLogLoggerSettings); factory.AddProvider(nLogLoggerProvider); // Create real logger ILogger logger = factory.CreateLogger(nameof(NLogLoggerTest)); Assert.AreEqual(1, nLogLoggerProvider.NLogLoggers.Count); // Send the log message EventId eventId = new EventId(1, nameof(EventId)); Exception exception = new Exception(); string message = "Message-{param}"; object[] args = new object[] { "param" }; logger.LogDebug(eventId, exception, message, args); NLogLogger lst; Assert.IsTrue(nLogLoggerProvider.NLogLoggers[nameof(NLogLoggerTest)].TryGetTarget(out lst)); // check the filter Assert.AreEqual(nameof(NLogLoggerTest), category); Assert.AreEqual(LogLevel.Debug, logLevel); }
public void CreateAnyLoggerWithAlias2Negative() { LoggerFactory factory = new LoggerFactory(); NLogLoggerSettings nLogLoggerSettings = new NLogLoggerSettings { }; nLogLoggerSettings.AcceptedCategoryNames = new List <string> { "f*", "*name" }; nLogLoggerSettings.AcceptedAliasesCategoryNames = new Dictionary <string, string> { { "f*", "Remap1" }, { "*name", "Remap2" } }; NLogLoggerProvider nLogLoggerProvider = new NLogLoggerProvider(nLogLoggerSettings); var logger = nLogLoggerProvider.CreateLogger("Abracadabra"); Assert.IsInstanceOfType(logger, typeof(Microsoft.Extensions.Logging.Abstractions.NullLogger)); logger = nLogLoggerProvider.CreateLogger("RoundNAmEs"); Assert.IsInstanceOfType(logger, typeof(Microsoft.Extensions.Logging.Abstractions.NullLogger)); }
/// <summary> /// The Startup constructor. /// </summary> /// <param name="configuration">The configuration.</param> /// <param name="environment">The environment.</param> public Startup(IConfiguration configuration, IHostEnvironment environment) { // Gets the factory for ILogger instances. var nlogLoggerProvider = new NLogLoggerProvider(); // Creates an ILogger. _logger = nlogLoggerProvider.CreateLogger(typeof(Startup).FullName); // Gets environment in the web.config file https://weblog.west-wind.com/posts/2020/Jan/14/ASPNET-Core-IIS-InProcess-Hosting-Issues-in-NET-Core-31 string environmentName = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"); _logger.LogInformation($"Environment name: {environmentName}"); var builder = new ConfigurationBuilder() .SetBasePath(environment.ContentRootPath) .AddEnvironmentVariables() .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) .AddJsonFile($"appsettings.{environmentName ?? "Production"}.json", optional: true); // Sets the new Configuration configuration = builder.Build(); Configuration = configuration; }
private static void TryLoadConfigurationFromSection(NLogLoggerProvider loggerProvider, IConfiguration configuration) { if (string.IsNullOrEmpty(loggerProvider.Options.LoggingConfigurationSectionName)) { return; } var nlogConfig = configuration.GetSection(loggerProvider.Options.LoggingConfigurationSectionName); if (nlogConfig?.GetChildren()?.Any() == true) { loggerProvider.LogFactory.Setup().LoadConfiguration(configBuilder => { if (configBuilder.Configuration.LoggingRules.Count == 0 && configBuilder.Configuration.AllTargets.Count == 0) { configBuilder.Configuration = new NLogLoggingConfiguration(nlogConfig, loggerProvider.LogFactory); } }); } else { Common.InternalLogger.Debug("Skip loading NLogLoggingConfiguration from empty config section: {0}", loggerProvider.Options.LoggingConfigurationSectionName); } }
public NLoggerModule() { _provider = new NLogLoggerProvider(); }
public void TestOfCategoryNameMatcher() { NLogLoggerProvider prv = new NLogLoggerProvider(); Assert.AreEqual <(MatchPatternResult, string)>((MatchPatternResult.StartWith, "f*"), prv.MatchToPatternList("FaKeNamE", new List <string>() { "f*" })); Assert.AreEqual <(MatchPatternResult, string)>((MatchPatternResult.EndWith, "*name"), prv.MatchToPatternList("FaKeNamE", new List <string>() { "*name" })); Assert.AreEqual <(MatchPatternResult, string)>((MatchPatternResult.Contains, "*ENA*"), prv.MatchToPatternList("FaKeNamE", new List <string>() { "*ENA*" })); Assert.AreEqual <(MatchPatternResult, string)>((MatchPatternResult.Exact, "FAKENAME"), prv.MatchToPatternList("FaKeNamE", new List <string>() { "FAKENAME" })); Assert.AreEqual <(MatchPatternResult, string)>((MatchPatternResult.WildMatch, "*"), prv.MatchToPatternList("werftg", new List <string>() { "*" })); Assert.AreEqual <(MatchPatternResult, string)>((MatchPatternResult.None, string.Empty), prv.MatchToPatternList("", new List <string>() { "FAKENAME" })); Assert.AreEqual <(MatchPatternResult, string)>((MatchPatternResult.None, string.Empty), prv.MatchToPatternList("", new List <string>() { "FAKENAME" })); Assert.AreEqual <(MatchPatternResult, string)>((MatchPatternResult.None, string.Empty), prv.MatchToPatternList("FaKeNamE", new List <string>() { })); Assert.AreEqual <(MatchPatternResult, string, string)>((MatchPatternResult.StartWith, "f*", "Map"), prv.MatchToMappingPattern("FaKeNamE", new Dictionary <string, string>() { ["f*"] = "Map" })); Assert.AreEqual <(MatchPatternResult, string, string)>((MatchPatternResult.EndWith, "*name", "Map"), prv.MatchToMappingPattern("FaKeNamE", new Dictionary <string, string>() { ["*name"] = "Map" })); Assert.AreEqual <(MatchPatternResult, string, string)>((MatchPatternResult.Contains, "*ENA*", "Map"), prv.MatchToMappingPattern("FaKeNamE", new Dictionary <string, string>() { ["*ENA*"] = "Map" })); Assert.AreEqual <(MatchPatternResult, string, string)>((MatchPatternResult.Exact, "FAKENAME", "Map"), prv.MatchToMappingPattern("FaKeNamE", new Dictionary <string, string>() { ["FAKENAME"] = "Map" })); Assert.AreEqual <(MatchPatternResult, string, string)>((MatchPatternResult.WildMatch, "*", "Map"), prv.MatchToMappingPattern("werftg", new Dictionary <string, string>() { ["*"] = "Map" })); Assert.AreEqual <(MatchPatternResult, string, string)>((MatchPatternResult.None, string.Empty, string.Empty), prv.MatchToMappingPattern("", new Dictionary <string, string>() { ["FAKENAME"] = "Map" })); Assert.AreEqual <(MatchPatternResult, string, string)>((MatchPatternResult.None, string.Empty, string.Empty), prv.MatchToMappingPattern("", new Dictionary <string, string>() { ["FAKENAME"] = "Map" })); Assert.AreEqual <(MatchPatternResult, string, string)>((MatchPatternResult.None, string.Empty, string.Empty), prv.MatchToMappingPattern("FaKeNamE", new Dictionary <string, string>())); }