-
-
Notifications
You must be signed in to change notification settings - Fork 5
Event Metric Logging
Note: This page is a for a Work-In-Progress PR (#2849).
The event metric logging system is implemented via Interceptors using an Aspect-Oriented Programming pattern. This pattern means that the class which wishes to log event metrics does not need to know the details on how to log, such as what class, syntax, or format, but only needs to declare the functions that need to be logged as having executed and the scope of the event metric. The scope can be thought of as a category or grouping.
In most cases, the user identifier and project identifier will be retrieved from the userId
and projectId
function parameters (if present), but if these are not present, the correpsonding arguments will need to be specified.
- The class/interface that is to be intercepted must be
public
.- However, if the class or interface cannot be
public
:- Change the class or interface to
internal
- Mark the assembly as:
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
- Change the class or interface to
- However, if the class or interface cannot be
- If you are using
[LogEventMetric]
on a function in a class (not an interface), that function will need to bevirtual
.
This tutorial assumes that your class has an interface.
- In your interface, adding the following
using
declarations:
using Autofac.Extras.DynamicProxy;
using SIL.XForge.EventMetrics;
- Add the following attribute to your interface:
[Intercept(typeof(EventMetricLogger))]
public interface I...
- Add the following attribute to the function you wish to log the event metric of, choosing the scope you wish to use:
[LogEventMetric(EventScope.Drafting)]
void MyMethod(string userId, string projectId);
If your function does not use the standard parameter names of userId
or projectId
, declare these in the attribute:
[LogEventMetric(EventScope.Settings, nameof(curUserId), nameof(targetProjectId))]
void MyMethod(string curUserId, string targetProjectId);
Or, if they are in an object, declare them as follows:
[LogEventMetric(EventScope.Sync, "syncConfig.UserId", "syncConfig.ProjectId")]
Task<string> SyncAsync(SyncConfig syncConfiguration);
- Add the mapping for your interface and the class that implements it to
SFEventMetricsContainerBuilderExtensions.RegisterSFEventMetrics()
:
containerBuilder.RegisterEventMetrics<ISyncService, SyncService>();
-
Add the name of the function being logged, and description of it to the TypeScript function
getEventType()
inEventMetricsLogComponent.ts
. -
After running the application and executing the method that logs the event metric, check the
event_metrics
collection in MongoDB for your logged event metric.
Scopes are treated string values, and can be added as required. The name of the enum value will be its scope name in the database. These are defined in the enum EventScope
in the SIL.XForge project.
Using [LogEventMetric]
in an interface:
[Intercept(typeof(EventMetricLogger))]
public interface IMyService
{
[LogEventMetric(EventScope.Settings)]
void ThisMethodWillBeLogged();
void ThisMethodWillNot();
[LogEventMetric(EventScope.Settings)]
void ThisMethodUsesDefaultParameterNames(string userId, string projectId);
[LogEventMetric(EventScope.Settings, nameof(curUserId), nameof(targetProjectId))]
void ThisMethodUsesDifferentParameterNames(string curUserId, string targetProjectId);
[LogEventMetric(EventScope.Sync, "syncConfig.UserId", "syncConfig.ProjectId")]
void ThisMethodUsesAnObject(SyncConfig syncConfiguration);
[LogEventMetric(EventScope.Settings, captureReturnValue: true)]
string ThisWillCaptureTheReturnVAlue(string userId, string projectId);
}
Registering a class and interface for event metrics:
containerBuilder.RegisterEventMetrics<IMyService, MyService>();
Using [LogEventMetric]
in a class:
[Intercept(typeof(EventMetricLogger))]
public class MyService
{
[LogEventMetric(EventScope.Settings)]
public virtual void ThisMethodWillBeLogged() => ...
}
Registering a class which does not have an interface for event metrics:
containerBuilder.RegisterEventMetrics<MyService>();
- https://en.wikipedia.org/wiki/Aspect-oriented_programming - An introduction to aspect-oriented programming
- https://autofac.readthedocs.io/en/stable/advanced/interceptors.html - Information on the interceptors used to implement the event metric recording