logging - Correlation Token for Service Fabric Actors and Services -
we started playing service fabric microservice platform , after having succesfully implemented our firsts "hello world" samples actor pattern, stateless/stateful services, web api (and on) moving looking solutions other core aspects auth/autz , application logging.
i have doubt logging; in soa have designed till added "correlation token" services involved (often @ architectural level, automatically added header onto wcf, hidden developers) so, trying same service fabric.
looking best solution let flow "correlation token" through actor/service calls, since haven't found out ready out-of-the-box, wondering if looking theoretically wrong.
any suggestion out there?
i've had lot of success using serilog , seq , using enricher add properties log messages.
in services call servicelogger.createlogger(this) log enriched state service. if want correlation token should able add relatively easily, it's not i've done yet.
i think i've copied relevant code below!
public class servicefabricenricher<t> : ilogeventenricher t : servicecontext { protected t context { get; } private logeventproperty _nodename; public servicefabricenricher(t context) { context = context; } public virtual void enrich(logevent logevent, ilogeventpropertyfactory propertyfactory) { if (_nodename == null) _nodename = propertyfactory.createproperty("nodename", context.nodecontext.nodename); logevent.addpropertyifabsent(_nodename); } } public class serviceenricher<t> : servicefabricenricher<t> t : servicecontext { private logeventproperty _servicename; private logeventproperty _partitionid; private logeventproperty _applicationname; public serviceenricher(t context) : base(context) { } public override void enrich(logevent logevent, ilogeventpropertyfactory propertyfactory) { base.enrich(logevent, propertyfactory); if (_servicename == null) _servicename = propertyfactory.createproperty("servicename", context.servicename); if (_partitionid == null) _partitionid = propertyfactory.createproperty("partitionid", context.partitionid); if (_applicationname == null) _applicationname = propertyfactory.createproperty("applicationname", context.codepackageactivationcontext.applicationname); logevent.addpropertyifabsent(_servicename); logevent.addpropertyifabsent(_partitionid); logevent.addpropertyifabsent(_applicationname); } } public static class servicefabriclogger { private static ilogger createrdefaultlogger() { var configurationprovider = new fabricconfigurationprovider("seqconfig"); var loggerconfiguration = new loggerconfiguration(); if (configurationprovider.hasconfiguration) { var seqserver = configurationprovider.getvalue("seqserver"); loggerconfiguration = loggerconfiguration .writeto.seq(seqserver, period: timespan.frommilliseconds(500)) ; var level = configurationprovider.getvalue("minimumlevel"); logeventlevel minimumlevel; if (!string.isnullorwhitespace(level) && enum.tryparse<logeventlevel>(level, true, out minimumlevel)) { loggerconfiguration = loggerconfiguration.minimumlevel.is(minimumlevel); } } else { loggerconfiguration = loggerconfiguration .minimumlevel.error() ; } log.logger = loggerconfiguration.createlogger(); return log.logger; } public static ilogger logger { get; } = createrdefaultlogger(); } public static class servicelogger { public static ilogger createlogger(this statefulservicebase service) => servicefabriclogger.logger.forcontext(new[] { new statefulserviceenricher(service.context) }); public static ilogger createlogger(this statelessservice service) => servicefabriclogger.logger.forcontext(new[] { new statelessserviceenricher(service.context) }); }
Comments
Post a Comment