-
Notifications
You must be signed in to change notification settings - Fork 2
Defining Services
The stateful service is defined using DefineStatefulService(...)
method:
new HostBuilder()
.DefineStatefulService(serviceBuilder => { ... })
.Build()
.Run()
The stateless service is defined using DefineStatelessService(...)
method:
new HostBuilder()
.DefineStatelessService(serviceBuilder => { ... })
.Build()
.Run()
You can define more than one service using the same HostBuilder
instance. This is done using multiple calls to DefineStatefulService(...)
and DefineStatelessService(...)
methods:
new HostBuilder()
.DefineStatefulService(serviceBuilder => { ... })
.DefineStatefulService(serviceBuilder => { ... })
.DefineStatelessService(serviceBuilder => { ... })
.DefineStatelessService(serviceBuilder => { ... })
.Build()
.Run()
Warning
When configuring multiple services within the same assembly and these services use shared process hosting model then all statics are shared between services. More information about shared hosting process model can be found https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-hosting-model
All services has to be linked to the one of the service types declared in ServiceManifest.xml
.
<ServiceManifest Name="ServicePkg" Version="1.0.0">
<ServiceTypes>
<!-- @ServiceTypeName is the service type name. -->
<StatefulServiceType
ServiceTypeName="StatefulServiceType"
HasPersistedState="true" />
</ServiceTypes>
</ServiceManifest>
The linkage is done using UseServiceType(...)
method:
...
.DefineStatefulService(
serviceBuilder =>
{
// The value matches the @ServiceTypeName in ServiceManifest.xml
serviceBuilder.UseServiceType("StatefulServiceType");
})
...
ETW (Event Tracing for Windows) - is the recommended way to log service events. During initialization infrastructure creates an instance of self-descriptive EventSource
identified as AppType-ServiceType
. This instance is then used to support ILogger<T>
event redirection scenario (please see Understanding Logging).
The default behavior can be overridden using SetupEventSource(...)
method:
.DefineStatefulService(
serviceBuilder =>
{
serviceBuilder.SetupEventSource(eventSourceBuilder => { ... });
})
The re-configuration is done by overriding the implementation of the event source. This is done using UseImplementation(...)
method:
.DefineStatefulService(
serviceBuilder =>
{
serviceBuilder
.SetupEventSource(
eventSourceBuilder =>
{
eventSourceBuilder
.UseImplementation(() => ServiceEventSource.Current);
})
})
The UseImplementation(...)
method allows to specify a factory function used to create an instance of event source.
Information
The event source
class
should implementIServiceEventSource
interface. This is required to supportILogger<T>
event redirection.
Here is the example of event source class
implementation:
[EventSource(Name = "App-Service")]
internal sealed class ServiceEventSource
: EventSource, IServiceEventSource
{
public static class Keywords
{
public const EventKeywords ApiController = (EventKeywords) 0x4L;
}
private const int ServiceMessageEventId = 2;
private const int GetValueMethodInvokedId = 7;
public static readonly ServiceEventSource Current = new ServiceEventSource();
[Event(GetValueMethodInvokedId,
Level = EventLevel.Informational,
Message = "GetValueMethodInvoked",
Keywords = Keywords.ApiController)]
public void GetValueMethodInvoked()
{
this.WriteEvent(GetValueMethodInvokedId);
}
public void WriteEvent<T>(
ref T eventData)
where T : ServiceEventSourceData
{
this.ServiceMessage(
eventData.ServiceName,
eventData.ServiceTypeName,
eventData.ReplicaOrInstanceId,
eventData.PartitionId,
eventData.ApplicationName,
eventData.ApplicationTypeName,
eventData.NodeName,
eventData.EventMessage);
}
[Event(ServiceMessageEventId,
Level = EventLevel.Informational,
Message = "{7}")]
private void ServiceMessage(
string serviceName,
string serviceTypeName,
long replicaOrInstanceId,
Guid partitionId,
string applicationName,
string applicationTypeName,
string nodeName,
string message)
{
this.WriteEvent(
ServiceMessageEventId,
serviceName,
serviceTypeName,
replicaOrInstanceId,
partitionId,
applicationName,
applicationTypeName,
nodeName,
message);
}
}
This implementation has two events defined: ServiceMessage
and GetValueMethodInvoked
:
- The
ServiceMessage
event is used to write all entries redirected fromILogger<T>
. - The
GetValueMethodInvoked
method is intended to be used directly in code:ServiceEventSource.Current.GetValueMethodInvoked(...)
.
Writing events through ILogger<T>
doesn't allow you to leverage all the benefits of the EventSource
implementation. Thus infrastructure provides support for so called specialized interfaces. These interfaces are derived from IServiceEventSourceInterface
interface and allow you to setup a logging API surface for particular use cases.
public interface IApiServiceEventSource : IServiceEventSourceInterface
{
void GetValueMethodInvoked();
}
When event source class
implements a specialized interface then during initialization the same instance of event source is automatically registered in all dependency injection containers as interfaces, type and as IServiceEventSource
interface.
[EventSource(Name = "App-Service")]
internal sealed class ServiceEventSource
: EventSource,
IServiceEventSource,
IApiServiceEventSource
{
...
}
Usage of specialized interfaces allows to hide the implementation behind the specifically designed interface and leverage benefits of interface segregation and usage of EventSource
's methods.
Please see Defining Delegates documentation for a complete guide.
Please see Defining Listeners documentation for a complete guide.
(c) 2021 Coherent Solutions Inc.
GENERAL
GETTING STARTED
UNDERSTANDING THE PROJECT
SAMPLES