Fluid server package containing telemetry utilities used across Fluid service code.
See GitHub for more details on the Fluid Framework and packages within.
The services-telemetry package is built around 3 main components:
- A
Lumberjackclass: the main telemetry manager.Lumberjackis the telemetry interface to be used when instrumenting the code. It is a singleton responsible for managing a list of “engines” that implement the app-specific telemetry logic. It can be used to initialize a metric/data instance (which we callLumber). It also supports the logging functionality. - An
ILumberjackEngineinterface: defining the requirements for an implementation of the engines employed byLumberjack. Lumber: the self-contained class representing a metric or event.Lumbershould be created throughLumberjack, which will provideLumberwith the list ofLumberjackEnginesthat define how to handle the data. After being created,Lumbercan be used to add properties to a property bag and can be finally completed either as a successful or failed operation, while keeping track of duration of the event.
The idea behind Lumberjack is convenience, available through a globally accessible telemetry tool. It is customizable through the app-specific ILumberjackEngine implementations and is capable of handling 2 types of telemetry data. Metrics represent events or operations that can usually be associated with a result of success or failure, that can be measured in terms of duration and that can generally be used in the context of service monitoring/alerting. Logs, on the other hand, should be used in situations where there is no event being evaluated; in other words, where there is not an associated concept of success or failure, duration, etc.
At the start of each Node.js process, Lumberjack should be initialized so that it can be used in singleton style throughout the code. However, it is also possible to create individual instances of Lumberjack at any time. Lumberjack must be initialized with a mandatory ILumberjackEngine[] parameter (it uses each ILumberjackEngine in the list to emit the telemetry data according to the ILumberjackEngine logic). Lumberjack can also take an optional ILumberjackSchemaValidator, which defines the requirements for mandatory parameters and values associated with each Lumber instance.
In these examples, we will be using WinstonLumberjackEngine as our ILumberjackEngine sample implementation.
// Singleton style, at the start of each process
const lumberjackEngine = new WinstonLumberjackEngine();
Lumberjack.setup([lumberjackEngine]);
// Instance style
const lumberjackEngine = new WinstonLumberjackEngine();
const customInstance = Lumberjack.createInstance([lumberjackEngine]);In FluidFramework Server code, Lumberjack initialization is taken care of automatically thanks to configureLogging() in the server-services-utils package.
Metrics are associated with types of events, and each event type should have a unique name. The list of Events is kept in the LumberEventName enum. Lumberjack also supports simple string event names. Example:
const lumberJackMetric = Lumberjack.newLumberMetric(LumberEventName.DeliHandler);
lumberJackMetric.setProperties({
[BaseTelemetryProperties.tenantId]: this.tenantId,
[BaseTelemetryProperties.documentId]: this.documentId,
});
try {
... // Event being tracked
lumberJackMetric.success("Success message!");
}
catch (error) {
lumberJackMetric.error("Error message :(", error);
}Lumberjack provides a static method for logging. Example:
const props = {
property1: "prop1",
property2: "prop2",
};
Lumberjack.log("Sample message", LogLevel.Info, properties);