This package exposes a DvelopLogger
-class which is initialized with a level
and 1-n Providers
. See Concepts for more information.
const logger = new DvelopLogger({
level: "info",// logs info and above
providers: [
// Providers define a logging scheme. Currently only OTEL is supported.
otelProviderFactory({
appName: "acme-myapp",
appVersion: "1.0.0",
instanceId: "0",
// Transports define where to logging statements are send. Multiple transports can be used.
transports: [
consoleTransportFactory(), // logs to console
fileTransportFactory("./logs.txt") // logs to file 'logs.txt'
]
})
],
});
Supported LogLevels are debug
, info
and error
, represented by exposed methods.
The minimal logstatement defines a level and a string to log. The OTEL-Provider transforms the information.
logger.debug({}, "Hello World!");
/**
* {
* "time":"2022-07-07T11:06:34.105Z",
* "sev":9,
* "body":"Hello World!",
* "res":{
* "svc":{
* "name":"acme-myapp",
* "ver":"1.0.0"
* "inst": "0"
* }
* },
* "vis":1
* }
*/
For each method the first argument is a DvelopContext
-object and the second argument a DvelopLogEvent
-object.
try {
convinceLeonidasThatThisIsMadness();
} catch (error: any) {
logger.error({
systemBaseUri: "https://sparta.d-velop.cloud",
tenantId: "T8r3cWM4JII"
}, {
name: "MissionFailedLogger",
message: "Apparently this is Sparta",
error: error,
customAttributes: {
learnings: "Don't stand near a well"
}
});
}
/**
* {
* "time":"479BCT11:11:11.111Z",
* "sev":17,
* "name":"MissionFailedLogger",
* "body":"Apparently this is Sparta",
* "tn":"T8r3cWM4JII",
* "res":{
* "svc":{
* "name":"acme-myapp",
* "ver":"1.0.0",
* "inst": "0"
* }
* },
* "attr":{
* "learnings":"Don't stand near a well",
* "exception":{
* "message":"THIS IS SPARTA",
* "type":"RoundHouseKickError",
* "stacktrace":"..."
* }
* },
* "vis":1
* }
*/
In this package logging is divided over three layers
- Transports
- Providers
- Logger
Transports are responsible for transporting a log-event. Transports are agnostic about the form of the log event.
export type TransportFn = (event: any) => Promise<void>;
There are currently two default transports supported:
import { TransportFn, consoleTransportFactory, fileTransportFactory } from "@dvelop-sdk/logging";
const consoleTransport: TransportFn = consoleTransportFactory();
await consoleTransport("Hello World!"); // log "Hello World" to console in Node.js and Browsers
const fileTransport: TransportFn = fileTransportFactory("./logs.txt");
await fileTransport("Hello World!"); // log "Hello World" to logs.txt
You can easily implement your own Transport-Function:
async function myTransport(event: any): Promise<void> {
// jump through hoops
}
Providers are able to work with the DvelopLogEvent
-Type. The do transformation and may support any Transport-Functions, a subset or none (e.g a Syslog-Provider could have a UDP Transport to Port 514 baked in).
export type ProviderFn = (context: DvelopContext, event: DvelopLogEvent, level: DvelopLogLevel) => Promise<void>;
One default Provider is supported:
import { ProviderFn, otelProviderFactory } from "@dvelop-sdk/logging";
const otel: ProviderFn = otelProviderFactory({
appName: "acme-myapp",
appVersion: "1.0.0",
instanceId: "0",
transports: [ consoleTransport, fileTransport, myTransport ]
});
D.velop default is to log in a JSON-Format derived from the Open Telemetry Standard. The otelProviderFactory
creates a ProviderFn
that is responsable for according transformations (e.g. map level "info" to OTELs numeric severity of 9).
You can easily implement your own Provider-Function:
// do a fixed provider
async function myProvider(context: DvelopContext, event: DvelopLogEvent, level: DvelopLogLevel): Promise<void> {
// jump through hoops
}
// or have some init
async function myProviderFactory(howMuchIsTheFish: number): ProviderFn {
return (context: DvelopContext, event: DvelopLogEvent, level: DvelopLogLevel) => Promise<void> {
// jump through hoops
}
}
// or even support generic TransportFunctions
async function myProviderFactory(transports: TransportFn[]): ProviderFn {
return (context: DvelopContext, event: DvelopLogEvent, level: DvelopLogLevel) => Promise<void> {
const formattedEvent: any = {} // jump through hoops
transports.forEach(t => t(formattedEvent));
}
}
Finally we have that can log something. The DvelopLogger
accepts a level (everything above is logged) and 1-n provider-functions.
const logger = new DvelopLogger({
level: "info",
providers: [
otelProviderFactory({
appName: "acme-myapp",
appVersion: "1.0.0",
instanceId: "0",
transports: [
consoleTransportFactory(),
fileTransportFactory("./logs.txt")
]
})
],
});