@solusyon/metrics
v0.2.1
Published
Metrics library for Node.js APIs.
Maintainers
Readme
@solusyon/metrics
TypeScript library for execution tracking with traceId, execution time, and error capture.
Runtime requirements
- Node.js
20or higher
Installation
npm install @solusyon/metricsAvailable API
startTracking(config, fn)startTrackingMetrics(traceId, fn, sampleRate?)- deprecated compatibility aliasgetTraceId()getMetadata()addMetadata(entries)setMetricsLogger(loggerBuilder)measureFunctionWrapper(fn, name?)measureObjectWrapper(obj, name)MeasureClass()
Example 1: isolated function
import {
getTraceId,
measureFunctionWrapper,
startTracking,
} from "@solusyon/metrics";
const chargePayment = measureFunctionWrapper(async (orderId: string) => {
const traceId = getTraceId();
return { orderId, status: "paid", traceId };
}, "chargePayment");
const result = await startTracking(
{ traceId: "req-123", sampleRate: 1 },
async () => {
return chargePayment("order-1");
},
);
console.log(result);Example 2: object with multiple methods
import { measureObjectWrapper, startTracking } from "@solusyon/metrics";
const repository = {
async findUser(id: string) {
return { id, name: "Anderson" };
},
async updateUser(id: string, name: string) {
return { id, name };
},
};
const trackedRepository = measureObjectWrapper(repository, "UserRepository");
await startTracking({ traceId: "req-456", sampleRate: 1 }, async () => {
const user = await trackedRepository.findUser("u-1");
await trackedRepository.updateUser(user.id, "New Name");
});Example 3: class with decorator
import { MeasureClass, startTracking } from "@solusyon/metrics";
class CheckoutService {
async createOrder() {
return { id: "ord-1", status: "created" };
}
}
MeasureClass()(CheckoutService);
const service = new CheckoutService();
await startTracking({ traceId: "req-789", sampleRate: 1 }, async () => {
await service.createOrder();
});Example 4: with metadata
import {
addMetadata,
getMetadata,
measureFunctionWrapper,
startTracking,
} from "@solusyon/metrics";
const processPayment = measureFunctionWrapper(async (amount: number) => {
const metadata = getMetadata();
return { amount, userId: metadata?.userId };
}, "processPayment");
await startTracking(
{ traceId: "req-111", sampleRate: 1, metadata: { userId: "user-42" } },
async () => {
addMetadata({ environment: "production" });
const result = await processPayment(100);
console.log(result);
},
);Example 5: custom logger
import { setMetricsLogger } from "@solusyon/metrics";
setMetricsLogger((format) => {
return (data) => {
const message = format(data);
// send to Datadog, OpenSearch, CloudWatch, etc.
console.log(JSON.stringify({ level: "debug", message }));
};
});How sampling works
sampleRateranges from0to1and is internally limited to the range0.001to1.- If
sampleRateis not provided, the library uses theMETRICS_SAMPLE_RATEenvironment variable. - If the variable does not exist, the current default is
1. - If
traceIdis omitted instartTracking, the library generates one withrandomUUID().
Scripts
npm run build: generates artifacts indist/npm run check: validates types without generating buildnpm test: runs the test suitenpm run test:watch: runs tests in watch mode
Publishing to npm
- Log in:
npm login - Update version:
npm version patch(orminor/major) - Publish:
npm publish --access public
Pipeline (GitHub Actions)
- On
pull_requestandpushtomain: runsnpm ci,npm run check,npm run build, andnpm pack --dry-run. - On
pushof tagv*(e.g.,v0.1.1): in addition to validation, publishes to npm.
Required Configuration
- Create the
NPM_TOKENsecret in the GitHub repository with an npm token with publishing permission. - Generate a semantic tag and push to remote:
git tag v0.1.1
git push origin v0.1.1Important about package name
npm requires package names in lowercase. Therefore, the name was defined as @solusyon/metrics.
