Skip to content

Commit

Permalink
feat(logger): add MemoryLogger, ALogger
Browse files Browse the repository at this point in the history
- extract abstract ALogger
- add MemoryLogger
- refactor ConsoleLogger
- add LogEntry tuple type (migrated from @thi.ng/rstream-log)
- add tests
  • Loading branch information
postspectacular committed Aug 3, 2022
1 parent 24ec274 commit b2cd409
Show file tree
Hide file tree
Showing 7 changed files with 200 additions and 115 deletions.
165 changes: 86 additions & 79 deletions packages/logger/package.json
Original file line number Diff line number Diff line change
@@ -1,81 +1,88 @@
{
"name": "@thi.ng/logger",
"version": "1.1.9",
"description": "Types & basis infrastructure for arbitrary logging (w/ default impls)",
"type": "module",
"module": "./index.js",
"typings": "./index.d.ts",
"sideEffects": false,
"repository": {
"type": "git",
"url": "https://github.com/thi-ng/umbrella.git"
},
"homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/logger#readme",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/postspectacular"
},
{
"type": "patreon",
"url": "https://patreon.com/thing_umbrella"
}
],
"author": "Karsten Schmidt <k+npm@thi.ng>",
"license": "Apache-2.0",
"scripts": {
"build": "yarn clean && tsc --declaration",
"clean": "rimraf '*.js' '*.d.ts' '*.map' doc",
"doc": "typedoc --excludePrivate --excludeInternal --out doc src/index.ts",
"doc:ae": "mkdir -p .ae/doc .ae/temp && api-extractor run --local --verbose",
"doc:readme": "yarn doc:stats && tools:readme",
"doc:stats": "tools:module-stats",
"pub": "yarn npm publish --access public"
},
"devDependencies": {
"@microsoft/api-extractor": "^7.25.0",
"rimraf": "^3.0.2",
"tools": "workspace:^",
"typedoc": "^0.22.17",
"typescript": "^4.7.4"
},
"keywords": [
"console",
"logger",
"filter",
"typescript"
],
"publishConfig": {
"access": "public"
},
"browser": {
"process": false,
"setTimeout": false
},
"engines": {
"node": ">=12.7"
},
"files": [
"*.js",
"*.d.ts"
],
"exports": {
".": {
"default": "./index.js"
},
"./api": {
"default": "./api.js"
},
"./console": {
"default": "./console.js"
},
"./null": {
"default": "./null.js"
}
},
"thi.ng": {
"related": [
"rstream-log"
]
}
"name": "@thi.ng/logger",
"version": "1.1.9",
"description": "Types & basis infrastructure for arbitrary logging (w/ default impls)",
"type": "module",
"module": "./index.js",
"typings": "./index.d.ts",
"sideEffects": false,
"repository": {
"type": "git",
"url": "https://github.com/thi-ng/umbrella.git"
},
"homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/logger#readme",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/postspectacular"
},
{
"type": "patreon",
"url": "https://patreon.com/thing_umbrella"
}
],
"author": "Karsten Schmidt <k+npm@thi.ng>",
"license": "Apache-2.0",
"scripts": {
"build": "yarn clean && tsc --declaration",
"clean": "rimraf '*.js' '*.d.ts' '*.map' doc",
"doc": "typedoc --excludePrivate --excludeInternal --out doc src/index.ts",
"doc:ae": "mkdir -p .ae/doc .ae/temp && api-extractor run --local --verbose",
"doc:readme": "yarn doc:stats && tools:readme",
"doc:stats": "tools:module-stats",
"pub": "yarn npm publish --access public",
"test": "tools:node-esm test/index.ts"
},
"devDependencies": {
"@microsoft/api-extractor": "^7.25.0",
"rimraf": "^3.0.2",
"tools": "workspace:^",
"typedoc": "^0.22.17",
"typescript": "^4.7.4"
},
"keywords": [
"console",
"logger",
"filter",
"typescript"
],
"publishConfig": {
"access": "public"
},
"browser": {
"process": false,
"setTimeout": false
},
"engines": {
"node": ">=12.7"
},
"files": [
"*.js",
"*.d.ts"
],
"exports": {
".": {
"default": "./index.js"
},
"./alogger": {
"default": "./alogger.js"
},
"./api": {
"default": "./api.js"
},
"./console": {
"default": "./console.js"
},
"./memory": {
"default": "./memory.js"
},
"./null": {
"default": "./null.js"
}
},
"thi.ng": {
"related": [
"rstream-log"
]
}
}
36 changes: 36 additions & 0 deletions packages/logger/src/alogger.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { ILogger, LogLevel, LogLevelName } from "./api.js";

/**
* Abstract {@link ILogger} base implementation.
*/
export abstract class ALogger implements ILogger {
id: string;
level: LogLevel;

constructor(id: string, level: LogLevel | LogLevelName = LogLevel.FINE) {
this.id = id;
this.level = typeof level === "string" ? LogLevel[level] : level;
}

fine(...args: any[]): void {
this.level <= LogLevel.FINE && this.log(LogLevel.FINE, args);
}

debug(...args: any[]): void {
this.level <= LogLevel.DEBUG && this.log(LogLevel.DEBUG, args);
}

info(...args: any[]): void {
this.level <= LogLevel.INFO && this.log(LogLevel.INFO, args);
}

warn(...args: any[]): void {
this.level <= LogLevel.WARN && this.log(LogLevel.WARN, args);
}

severe(...args: any[]): void {
this.level <= LogLevel.SEVERE && this.log(LogLevel.SEVERE, args);
}

protected abstract log(level: LogLevel, args: any[]): void;
}
22 changes: 22 additions & 0 deletions packages/logger/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,25 @@ export interface ILogger {
warn(...args: any[]): void;
severe(...args: any[]): void;
}

/**
* Tuple type describing a single log entry.
*/
export interface LogEntry extends Array<any> {
/**
* Entry's associated log level
*/
[0]: LogLevel;
/**
* Logger ID
*/
[1]: string;
/**
* Timestamp
*/
[2]: number;
/**
* Log entry body (any number/type of arguments given)
*/
[id: number]: any;
}
37 changes: 5 additions & 32 deletions packages/logger/src/console.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,11 @@
import { ILogger, LogLevel } from "./api.js";
import { ALogger } from "./alogger.js";
import { LogLevel } from "./api.js";

/**
* {@link ILogger} implementation writing messages via `console.log`.
*/
export class ConsoleLogger implements ILogger {
id: string;
level: LogLevel;

constructor(id: string, level = LogLevel.FINE) {
this.id = id;
this.level = level;
}

fine(...args: any[]): void {
this.level <= LogLevel.FINE && this.log("FINE", args);
}

debug(...args: any[]): void {
this.level <= LogLevel.DEBUG && this.log("DEBUG", args);
}

info(...args: any[]): void {
this.level <= LogLevel.INFO && this.log("INFO", args);
}

warn(...args: any[]): void {
this.level <= LogLevel.WARN && this.log("WARN", args);
}

severe(...args: any[]): void {
this.level <= LogLevel.SEVERE && this.log("SEVERE", args);
}

protected log(level: string, args: any[]) {
console.log(`[${level}] ${this.id}:`, ...args);
export class ConsoleLogger extends ALogger {
protected log(level: LogLevel, args: any[]) {
console.log(`[${LogLevel[level]}] ${this.id}:`, ...args);
}
}
1 change: 1 addition & 0 deletions packages/logger/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from "./api.js";
export * from "./console.js";
export * from "./memory.js";
export * from "./null.js";
19 changes: 19 additions & 0 deletions packages/logger/src/memory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { ALogger } from "./alogger.js";
import type { LogEntry, LogLevel, LogLevelName } from "./api.js";

export class MemoryLogger extends ALogger {
journal: LogEntry[] = [];

constructor(
id: string,
level?: LogLevel | LogLevelName,
public limit = 1e3
) {
super(id, level);
}

protected log(level: LogLevel, args: any[]) {
if (this.journal.length >= this.limit) this.journal.shift();
this.journal.push([level, this.id, Date.now(), ...args]);
}
}
35 changes: 31 additions & 4 deletions packages/logger/test/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,32 @@
import { group } from "@thi.ng/testament";
// import * as assert from "assert";
// import { } from "../src/index.js"
import * as assert from "assert";
import { LogEntry, LogLevel, MemoryLogger } from "../src/index.js";

group("logger", {});
const journalWithoutTimestamp = (journal: LogEntry[]) =>
journal.map((x) => {
const y = x.slice();
y.splice(2, 1); // remove timestamp
return y;
});

const logger = new MemoryLogger("test", LogLevel.DEBUG, 3);
logger.fine(1, 2, 3);
logger.debug(1, 2, 3);
logger.info([1, 2, 3]);
assert.strictEqual(logger.journal.length, 2);
logger.warn("abc");
assert.strictEqual(logger.journal.length, 3);

assert.deepEqual(journalWithoutTimestamp(logger.journal), [
[LogLevel.DEBUG, "test", 1, 2, 3],
[LogLevel.INFO, "test", [1, 2, 3]],
[LogLevel.WARN, "test", "abc"],
]);

logger.warn("def");
assert.strictEqual(logger.journal.length, 3);

assert.deepEqual(journalWithoutTimestamp(logger.journal), [
[LogLevel.INFO, "test", [1, 2, 3]],
[LogLevel.WARN, "test", "abc"],
[LogLevel.WARN, "test", "def"],
]);

0 comments on commit b2cd409

Please sign in to comment.