Initial problem
It’s the classic logging issue again! In the Warehouse Management system that I’m working on, the team usually needs to add this logging pattern
const sendToteToPackingStation = (warehouseId: string, toteId: string): Promise<Result> => {
logger.info('Sending tote to packing station', { warehouseId, toteId });
const result = await someLogic(...);
logger.info('Send tote result', { result });
return result;
};
The purpose is simple. It’s what you have to do for production debugging in every system. You should write out some unique ids so you have a place to start querying your logging system. From that point, you will then trace the related entries using a correlation id that your system provides.
From time to time, when the system scaled up, there were new areas that could slow down the system. We then added more logging logic to the system, for example, execution time logging to help build some visualization dashboards to identify the root cause.
const sendToteToPackingStation = (warehouseId: string, toteId: string): Promise<Result> => {
const startTime = performance.now();
logger.info('Sending tote to packing station', { warehouseId, toteId });
const result = await someLogic(...);
logger.info('Send tote result', { result });
logger.info('Execution time', { durationMs: elapsedTimeMs(startTime) });
return result;
};
Of course, when this was repeated multiple times, we started thinking about making a higher order function (HOF) to reuse everywhere is the system
First implementation…
Let’s begin with the type definition. Here are the generic types how a HOF looks like. It’s a function that receives a function and return another function with the same signature with the input function
export type WrappedFunction<
FunctionArgs extends ReadonlyArray<unknown>,
FunctionReturn
> = (...args: FunctionArgs) => FunctionReturn;
export type HigherOrderFunction = <
FunctionArgs extends ReadonlyArray<unknown>,
FunctionReturn
>(
func: WrappedFunction<FunctionArgs, FunctionReturn>
) => WrappedFunction<FunctionArgs, FunctionReturn>;