Gökhan GÖKALP
11.11.2017
Devnot
Logging, Caching and Localization in Asp.NET Core 2.0
How to create log?
public class TodoController : Controller
{
private readonly ILogger<TodoController> _logger;
public TodoController(ILogger<TodoController> logger)
{
_logger = logger;
}
}
public IActionResult Index()
{
_logger.LogInformation(1000, "Index method invoked.");
return View();
}
How to add providers?
"Console" and "Debug" logging provider default template.
ConfigureLogging((hostingContext, logging) =>
{
logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
logging.AddConsole();
logging.AddDebug();
})
How to add providers?
Use several built-in logging providers with the "ConfigureLogging()" method on WebHost builder.
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.ConfigureLogging((hostingContext, logging) =>
{ logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
logging.AddConsole();
})
.Build();
Log Category, Log Levels and Log Event Id
info: DotNETCoreDay.Controllers.TodoController[1000]
Index method invoked.
DotNETCoreDay.Controllers.TodoController:Information: Index method invoked
Two ways to create log category:
Two ways to create log level:
Log Category, Log Levels and Log Event Id
Use "log event id" to groupe related messages.
info: DotNETCoreDay.Controllers.TodoController[1002] //Get operations
Getting item invalidid
warn: DotNETCoreDay.Controllers.TodoController[4000]
GetById(invalidid) NOT FOUND
Log Exceptions
Use "LogError()" method.
catch(Exception ex)
{
_logger.LogError(1001, ex, "Oops!");
}
Log Filtering Rules
Specify minimum log levels in "appsettings" easily.
{
"Logging": {
"Console": {
"LogLevel":{
"DotNETCoreDay.Controllers.HomeController" : "Information"
}
},
"LogLevel": {
"Default": "Debug"
}
}
}
or in "Program.cs":
WebHost.CreateDefaultBuilder(args)
.ConfigureLogging((hostingContext, logging) =>
{
logging.AddFilter<ConsoleLoggerProvider>("DotNETCoreDay.Controllers.TodoController",
LogLevel.Information);
logging.SetMinimumLevel(LogLevel.Debug); //Default value is "Information"
})
.Build();
Log Scopes
Useful for grouping some logical operations. E.g:
private void DoSomething()
{
using(_logger.BeginScope("DoSomething scope!"))
{
_logger.LogInformation(1000, "DoSomething method invoked.");
//..
_logger.LogWarning(1002, "Something happened!");
}
}
To activating scopes:
WebHost.CreateDefaultBuilder(args)
.ConfigureLogging((hostingContext, logging) =>
{
logging.AddConsole(options => options.IncludeScopes = true);
})
.Build();
{
"Logging": {
"IncludeScopes": true
}
}
or
Third-party Logging Providers
Asp.NET Core 2.0 supports popular logging providers. E.g:
Response Caching Middleware
public void ConfigureServices(IServiceCollection services)
{
services.AddResponseCaching(options => {
options.UseCaseSensitivePaths = false;
});
}
Configure in "Startup.cs"
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseResponseCaching();
}
Response Caching Middleware
[ResponseCache(Duration = 20)] //second
public IActionResult Index()
{
return View();
}
ResponseCache attribute
Some HTTP directives (Cache-Control)
HTTP 1.1 Caching specification
Response Caching Middleware
ResponseCache attribute - VaryByQueryKeys
Request | Result |
---|---|
http://example.com?key1=value1 | Returned from server |
http://example.com?key1=value1 | Returned from middleware |
http://example.com?key1=value2 | Returned from server |
Response Caching Middleware
ResponseCache attribute - Vary
[ResponseCache(VaryByHeader = "Accept-Language")]
public IActionResult Index()
{
return View();
}
Response Caching Middleware
ResponseCache attribute - Cache Profiles
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(options =>
{
options.CacheProfiles.Add("Default",
new CacheProfile()
{
Duration = 60 //Second
})
});
}
[ResponseCache(CacheProfileName = "Default"]
public IActionResult Index()
{
return View();
}
Memory Cache
public void ConfigureServices(IServiceCollection services)
{
services.AddMemoryCache();
}
readonly IMemoryCache _memoryCache;
TodoController(IMemoryCache memoryCache)
{
_memoryCache = memoryCache;
}
CustomerModel GetCustomer(int id)
{
CustomerModel customerModel;
if(!_memoryCache.TryGetValue(id, out customerModel))
{
customerModel = //...
var memoryCacheEntryOptions = new MemoryCacheEntryOptions()
{
SlidingExpiration = TimeSpan.FromMinutes(5)
};
_memoryCache.Set(id, customerModel, memoryCacheEntryOptions);
}
return customerModel;
}
Distributed Caching
How to use?
services.AddDistributedRedisCache(options =>
{
options.Configuration = "localhost:6379";
options.InstanceName = "master";
});
readonly IDistributedCache _distributedCache;
public TodoController(IDistributedCache distributedCache)
{
_distributedCache = distributedCache;
}
For localization:
Make the App's Content Localizable
public class TodoController : Controller
{
private readonly IStringLocalizer<TodoController> _localizer;
public TodoController(IStringLocalizer<TodoController> localizer)
{
_localizer = localizer;
}
public IActionResult Index()
{
CultureModel cultureModel = new CultureModel();
cultureModel.Title = _localizer["Merhaba Dünya!"];
return View(cultureModel);
}
}
Make the App's Content Localizable
public class TodoController : Controller
{
private readonly IStringLocalizer _localizerForShared;
public CulturesController(IStringLocalizerFactory localizerFactory)
{
_localizerForShared = localizerFactory.Create(typeof(SharedResource));
}
}
IStringLocalizerFactory (e.g shared resources)
Resource path: controller file path
Make the App's Content Localizable
@using Microsoft.AspNetCore.Mvc.Localization
@inject IViewLocalizer Localizer
@{
ViewData["Title"] = Localizer["Merhaba Dünya!"];
}
View Localization - IViewLocalizer
Resource path: view file path
Make the App's Content Localizable
public class CreateCultureModel
{
[Required(ErrorMessage = "This field is required.")]
public string Name { get; set; }
}
DataAnnotations Localization
Configuring Localization
public void ConfigureServices(IServiceCollection services)
{
services.AddLocalization(options => {
options.ResourcesPath = "Resources";
});
services.AddMvc()
.AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
.AddDataAnnotationsLocalization(options =>
{
options.DataAnnotationLocalizerProvider = (type, factory) => {
return factory.Create(typeof(SharedResource));
}
});
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
var lockOptions = app.ApplicationServices.GetService<IOptions<RequestLocalizationOptions>>();
app.UseRequestLocalization(lockOptions.Value);
}
How to add localization to service collection?
Configuring Localization
public void ConfigureServices(IServiceCollection services)
{
services.Configure<RequestLocalizationOptions>(options => {
var supportedCultures = new List<CultureInfo>
{
new CultureInfo("tr-TR"),
new CultureInfo("en-US")
};
options.DefaultRequestCulture = new RequestCulture("tr-TR");
options.SupportedCultures = supportedCultures;
options.SupportedUICultures = supportedCultures;
});
}
SupportedCultures(date, currency etc.) and SupportedUICultures(translate)
Implement a Strategy to Select the Language
3 options with RequestLocalization