In this blog, I will delve into using a typescript method decorator for tracking latency for any piece of code.
We have a lot of function calls in our code where we start the timer, calculate the time elapsed, and then publish it to some metric service.
async function testFunction() : Promise<void> {
try {
const now = Date.now();
/// logic here
///
} finally {
const timeElapsed = Date.now() - now
Metrics.push(timeElapsed)
}
}
It was a lot of repeated code and later we came across a typescript decorator which became really helpful in solving our issue. Typescript method decorators are just annotations that can be put on top of any method and then the function is called through the code that is behind that annotation.
So the code becomes
@latency
async function testFunction() : Promise<void> {
try {
const now = Date.now();
/// logic here
///
} finally {
const timeElapsed = Date.now() - now
Metrics.push(timeElapsed)
}
}
Now first, let's understand code buleprint for annotation.
Annotation code is injected during compile time
export function latency(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
//target is target class where this annotation is written
// propertyKey is name of the method, on which annotation is called
// descriptor contains all information about original method which is being decorated
}
export function latency(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
/// overwriting the original method
descriptor.value = async function(...args: any[]) {
const startTime = Date.now();
try {
const result = await originalMethod.apply(this, args);
return result;
} finally {
const timeElapsed = Date.now() - startTime;
Metrics.push(timeElapsed)
}
};
return descriptor;
}
Happy Coding ๐