Přidání protokolování do aplikace Service Fabric
Aplikace musí poskytnout dostatek informací pro forenzní ladění při vzniku problémů. Protokolování je jednou z nejdůležitějších věcí, které můžete přidat do aplikace Service Fabric. Když dojde k selhání, může vám dobré protokolování poskytnout způsob, jak prozkoumat selhání. Analýzou vzorů protokolů můžete najít způsoby, jak zlepšit výkon nebo návrh aplikace. Tento dokument ukazuje několik různých možností protokolování.
EventFlow
Sada knihoven EventFlow umožňuje aplikacím definovat, jaká diagnostická data se mají shromažďovat a kam se mají výstupovat. Diagnostická data můžou být cokoli od čítačů výkonu až po trasování aplikací. Běží ve stejném procesu jako aplikace, takže je minimalizovaná režie na komunikaci. Další informace o EventFlow a Service Fabric najdete v tématu Agregace událostí Azure Service Fabric s eventflow.
Použití strukturovaných událostí EventSource
Definování událostí zpráv podle případu použití umožňuje zabalit data o události v kontextu události. Snadněji můžete vyhledávat a filtrovat podle názvů nebo hodnot zadaných vlastností události. Strukturování výstupu instrumentace usnadňuje čtení, ale vyžaduje větší myšlenku a čas definovat událost pro každý případ použití.
Některé definice událostí je možné sdílet v celé aplikaci. Například spuštění nebo zastavení metody by se znovu použilo napříč mnoha službami v rámci aplikace. Služba specifická pro doménu, například systém objednávek, může mít událost CreateOrder , která má svou vlastní jedinečnou událost. Tento přístup může generovat mnoho událostí a potenciálně vyžadovat koordinaci identifikátorů napříč projektovými týmy.
[EventSource(Name = "MyCompany-VotingState-VotingStateService")]
internal sealed class ServiceEventSource : EventSource
{
public static readonly ServiceEventSource Current = new ServiceEventSource();
// The instance constructor is private to enforce singleton semantics.
private ServiceEventSource() : base() { }
...
// The ServiceTypeRegistered event contains a unique identifier, an event attribute that defined the event, and the code implementation of the event.
private const int ServiceTypeRegisteredEventId = 3;
[Event(ServiceTypeRegisteredEventId, Level = EventLevel.Informational, Message = "Service host process {0} registered service type {1}", Keywords = Keywords.ServiceInitialization)]
public void ServiceTypeRegistered(int hostProcessId, string serviceType)
{
WriteEvent(ServiceTypeRegisteredEventId, hostProcessId, serviceType);
}
// The ServiceHostInitializationFailed event contains a unique identifier, an event attribute that defined the event, and the code implementation of the event.
private const int ServiceHostInitializationFailedEventId = 4;
[Event(ServiceHostInitializationFailedEventId, Level = EventLevel.Error, Message = "Service host initialization failed", Keywords = Keywords.ServiceInitialization)]
public void ServiceHostInitializationFailed(string exception)
{
WriteEvent(ServiceHostInitializationFailedEventId, exception);
}
...
Obecné použití EventSource
Protože definování konkrétních událostí může být obtížné, mnoho lidí definuje několik událostí se společnou sadou parametrů, které obvykle vypíše jejich informace jako řetězec. Velká část strukturovaného aspektu je ztracena a hledání a filtrování výsledků je obtížnější. V tomto přístupu je definováno několik událostí, které obvykle odpovídají úrovním protokolování. Následující fragment kódu definuje ladicí a chybovou zprávu:
[EventSource(Name = "MyCompany-VotingState-VotingStateService")]
internal sealed class ServiceEventSource : EventSource
{
public static readonly ServiceEventSource Current = new ServiceEventSource();
// The Instance constructor is private, to enforce singleton semantics.
private ServiceEventSource() : base() { }
...
private const int DebugEventId = 10;
[Event(DebugEventId, Level = EventLevel.Verbose, Message = "{0}")]
public void Debug(string msg)
{
WriteEvent(DebugEventId, msg);
}
private const int ErrorEventId = 11;
[Event(ErrorEventId, Level = EventLevel.Error, Message = "Error: {0} - {1}")]
public void Error(string error, string msg)
{
WriteEvent(ErrorEventId, error, msg);
}
...
Použití hybridní strukturované a obecné instrumentace může také dobře fungovat. Strukturovaná instrumentace se používá k hlášení chyb a metrik. Obecné události se dají použít pro podrobné protokolování, které používají technici pro řešení potíží.
Microsoft.Extensions.Logging
Protokolování ASP.NET Core (balíček NuGet Microsoft.Extensions.Logging) je architektura protokolování, která poskytuje standardní rozhraní API pro protokolování pro vaši aplikaci. Podpora dalších back-endů protokolování je možné připojit k protokolování ASP.NET Core. Díky tomu získáte širokou škálu podpory pro zpracování protokolování v aplikaci, aniž byste museli měnit mnoho kódu.
Přidejte balíček NuGet Microsoft.Extensions.Logging do projektu, který chcete instrumentovat. Přidejte také všechny balíčky zprostředkovatele. Další informace najdete v tématu Protokolování v ASP.NET Core.
Přidejte do souboru služby direktivu using pro Microsoft.Extensions.Logging .
Definujte privátní proměnnou v rámci vaší třídy služby.
private ILogger _logger = null;
Do konstruktoru vaší třídy služby přidejte tento kód:
_logger = new LoggerFactory().CreateLogger<Stateless>();
Začněte instrumentovat kód ve svých metodách. Tady je několik ukázek:
_logger.LogDebug("Debug-level event from Microsoft.Logging"); _logger.LogInformation("Informational-level event from Microsoft.Logging"); // In this variant, we're adding structured properties RequestName and Duration, which have values MyRequest and the duration of the request. // Later in the article, we discuss why this step is useful. _logger.LogInformation("{RequestName} {Duration}", "MyRequest", requestDuration);
Použití jiných zprostředkovatelů protokolování
Někteří poskytovatelé třetích stran používají přístup popsaný v předchozí části, včetně serilogu, NLogu a Loggru. Každou z těchto možností můžete připojit k protokolování ASP.NET Core nebo je můžete použít samostatně. Serilog má funkci, která rozšiřuje všechny zprávy odeslané z protokolovacího nástroje. Tato funkce může být užitečná pro výstup názvu služby, typu a informací o oddílu. Pokud chcete tuto funkci použít v infrastruktuře ASP.NET Core, postupujte takto:
Přidejte do projektu balíčky Serilog, Serilog.Extensions.Logging, Serilog.Sinks.Literate a Serilog.Sinks.Observable NuGet.
Vytvořte
LoggerConfiguration
instanci protokolovacího nástroje a jeho instanci.Log.Logger = new LoggerConfiguration().WriteTo.LiterateConsole().CreateLogger();
Serilog.ILogger
Přidání argumentu do konstruktoru služby a předání nově vytvořeného protokolovacího nástroje.ServiceRuntime.RegisterServiceAsync("StatelessType", context => new Stateless(context, Log.Logger)).GetAwaiter().GetResult();
V konstruktoru služby vytvoří rozšíření vlastností pro ServiceTypeName, ServiceName, PartitionId a InstanceId.
public Stateless(StatelessServiceContext context, Serilog.ILogger serilog) : base(context) { PropertyEnricher[] properties = new PropertyEnricher[] { new PropertyEnricher("ServiceTypeName", context.ServiceTypeName), new PropertyEnricher("ServiceName", context.ServiceName), new PropertyEnricher("PartitionId", context.PartitionId), new PropertyEnricher("InstanceId", context.ReplicaOrInstanceId), }; serilog.ForContext(properties); _logger = new LoggerFactory().AddSerilog(serilog.ForContext(properties)).CreateLogger<Stateless>(); }
Instrumentujte kód stejně jako kdybyste používali ASP.NET Core bez Serilogu.
Poznámka:
Doporučujeme nepoužívat statickou funkci
Log.Logger
v předchozím příkladu. Service Fabric může hostovat více instancí stejného typu služby v rámci jednoho procesu. Pokud použijete statickouLog.Logger
funkci , zobrazí se poslední zapisovač pro rozšiřování vlastností hodnoty pro všechny spuštěné instance. To je jeden z důvodů, proč _logger proměnná je privátní členské proměnné třídy služby. Musíte také zpřístupnit_logger
běžný kód, který se může používat napříč službami.
Další kroky
- Přečtěte si další informace o monitorování aplikací v Service Fabric.
- Přečtěte si informace o protokolování pomocí EventFlow a diagnostiky Windows Azure.