Files
undead-logging/README.md

155 lines
4.2 KiB
Markdown

# Undead Logging
Logging for stupid idiots like me
* Pluggable event listeners
* Per-source hushing, global log type hushing
* Log timing control
* Time display modes
```ts
import Logging from "@proxnet/undead-logging"
const log = new Logging("Main");
log.i("Hello World!");
```
Disable a source:
```ts
// .. logging source is in the scope
log.visible = false;
log.debug("I can't be seen!");
// no output
```
Change a source's name:
```ts
// .. logging source "Main" is in the scope
log.n("Network is networking");
log.source = "Main2";
log.n("Something happened");
// output:
// 2024-11-14T01:21:40.350Z Main [NETWORK] Network is networking
// 2024-11-14T01:21:40.350Z Main2 [NETWORK] Something happened
```
Disable a type of message globally:
```ts
import Logging, { MessageTypeVisibility } from "@proxnet/undead-logging";
// .. logging source "Main" is in the scope
MessageTypeVisibility.Error = false;
// somewhere else, could be a different script
log.i("I am visible");
log.error("I am not visible");
// output:
// 2024-11-14T01:21:40.350Z Main [INFO] I am visible
```
## Event Listeners
Event listeners are called when a message is logged on any logging source
An event callback can either receive messages as either:
* Whole lines, including formatting, colors, excluding newlines
or
* Individual `msg` (string), `type` (MessageType), `source` (string), and `time` (Date) arguments
Callback ran when a message is logged anywhere:
```ts
LoggingListeners.onmsg('basic', msg => {
// `msg` is a string containing the entire line w/ formatting
});
```
Callback ran when a message is logged anywhere (this time components are split up):
```ts
LoggingListeners.onmsg('type', (msg, type, source, time) => {
// msg: string
// type: MessageType - import { MessageType } from "@proxnet/undead-logging";
// source: string
// time: Date
});
```
Remove callback:
```ts
const cb = msg => { /* do something with msg: string */ };
LoggingListeners.onmsg('basic', cb);
LoggingListeners.offmsg('basic', cb);
```
## Time display modes
You can display four different formats for time:
* UTC
* Unix time (in milliseconds)
* Local [process] time (in milliseconds, from the `performance` API)
* RoundedLocal: Same as above, but rounded to the nearest whole ms
Set the time format:
```ts
import { LoggingConfiguration, TimeFormat } from "@proxnet/undead-logging";
LoggingConfiguration.timeFormat = TimeFormat.Local;
// or
LoggingConfiguration.timeFormat = TimeFormat.Utc;
```
## (advanced) Logging timing
You can control when log functions are executed using `LoggingConfiguration.logTiming`.
Logs are sent synchronously by default. You can optionally defer logs with `setImmediate` using `LogTiming.Deferred`
```ts
LoggingConfiguration.logTiming = LogTiming.Sync;
// or
LoggingConfiguration.logTiming = LogTiming.Deferred;
```
You might prefer to defer logs in asynchronous situations where order does not matter and<br>
you'd like to prevent slowing down I/O.<br>
You might also prefer to reset all sources to synchronous logging during app shutdown.<br>
This can help debug issues with how your app closes. (see example below)
## Global resets
Every source is tracked by this module in a `Set`.
You can reset every source's log timing or time format with `LoggingConfiguration.reset(something)`.<br>
The corresponding property will be updated on `LoggingConfiguration`:
```ts
import Logging, { LoggingConfiguration, LogTiming } from "@proxnet/undead-logging";
const log = new Logging("Logger");
log.logTiming = LogTiming.Sync; // the default
LoggingConfiguration.resetLogTiming = LogTiming.Deferred;
// both are LogTiming.Deferred
log.d(`My log timing: LogTiming.${LogTiming[log.logTiming]}`);
log.d(`Global: LogTiming.${LogTiming[LoggingConfiguration.logTiming]}`);
```
This is useful when you want to use synchronous logging during a shutdown:
```ts
// something is keeping the event loop alive (HTTP server, a database, some I/O?)
LoggingConfiguration.logTiming = LogTiming.Deferred;
const log = new Logging("Main");
Deno.addSignalListener('SIGINT', () => {
LoggingConfiguration.resetLogTiming = LogTiming.Sync;
// shut down I/O here
});
```
## [Benchmarks](./BENCH.md)
## Contributing
create an account on gitea.proxnet.dev, fork, then PR