@timberio/core
Advanced tools
Comparing version 0.15.0 to 0.16.0
@@ -1,3 +0,2 @@ | ||
import { ITimberLog, Middleware, ITimberOptions, Sync } from "@timberio/types"; | ||
import { preProcess } from "./pipeline"; | ||
import { ITimberLog, ITimberOptions, LogLevel, Middleware, Sync } from "@timberio/types"; | ||
/** | ||
@@ -10,3 +9,3 @@ * Timber core class for logging to the Timber.io service | ||
protected _batch: any; | ||
protected _pipeline: (typeof preProcess)[]; | ||
protected _middleware: Middleware[]; | ||
protected _sync?: Sync; | ||
@@ -37,7 +36,45 @@ private _countLogged; | ||
* | ||
* @param log - Log entry | ||
* @returns Promise<ILog> - resolves to the transformed log | ||
* @param message: string - Log message | ||
* @param level (LogLevel) - Level to log at (debug|info|warn|error) | ||
* @param log: (Partial<ITimberLog>) - Initial log (optional) | ||
* @returns Promise<ITimberLog> after syncing | ||
*/ | ||
log(log: ITimberLog): Promise<ITimberLog>; | ||
log(message: string, level?: LogLevel, log?: Partial<ITimberLog>): Promise<ITimberLog>; | ||
/** | ||
* | ||
* Debug level log, to be synced with Timber.io | ||
* | ||
* @param message: string - Log message | ||
* @param log: (Partial<ITimberLog>) - Initial log (optional) | ||
* @returns Promise<ITimberLog> after syncing | ||
*/ | ||
debug(message: string, log?: Partial<ITimberLog>): Promise<ITimberLog>; | ||
/** | ||
* | ||
* Info level log, to be synced with Timber.io | ||
* | ||
* @param message: string - Log message | ||
* @param log: (Partial<ITimberLog>) - Initial log (optional) | ||
* @returns Promise<ITimberLog> after syncing | ||
*/ | ||
info(message: string, log?: Partial<ITimberLog>): Promise<ITimberLog>; | ||
/** | ||
* | ||
* Warning level log, to be synced with Timber.io | ||
* | ||
* @param message: string - Log message | ||
* @param log: (Partial<ITimberLog>) - Initial log (optional) | ||
* @returns Promise<ITimberLog> after syncing | ||
*/ | ||
warn(message: string, log?: Partial<ITimberLog>): Promise<ITimberLog>; | ||
/** | ||
* | ||
* Warning level log, to be synced with Timber.io | ||
* | ||
* @param message: string - Log message | ||
* @param log: (Partial<ITimberLog>) - Initial log (optional) | ||
* @returns Promise<ITimberLog> after syncing | ||
*/ | ||
error(message: string, log?: Partial<ITimberLog>): Promise<ITimberLog>; | ||
/** | ||
* Sets the sync method - i.e. the final step in the pipeline to get logs | ||
@@ -44,0 +81,0 @@ * over to Timber.io |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const types_1 = require("@timberio/types"); | ||
const tools_1 = require("@timberio/tools"); | ||
const pipeline_1 = require("./pipeline"); | ||
// Set default options for Timber | ||
const defaultOptions = { | ||
// Maximum number of logs to sync in a single request to Timber.io | ||
batchSize: 10, | ||
batchSize: 1000, | ||
// Max interval (in milliseconds) before a batch of logs proceeds to syncing | ||
@@ -26,4 +26,4 @@ batchInterval: 1000, | ||
constructor(apiKey, options) { | ||
// Transform pipeline | ||
this._pipeline = [pipeline_1.preProcess]; | ||
// Middleware | ||
this._middleware = []; | ||
// Number of logs logged | ||
@@ -33,2 +33,6 @@ this._countLogged = 0; | ||
this._countSynced = 0; | ||
// First, check we have a valid API key | ||
if (typeof apiKey !== "string" || apiKey === "") { | ||
throw new Error("Timber API key missing"); | ||
} | ||
// Store the API key, to use for syncing with Timber.io | ||
@@ -70,6 +74,8 @@ this._apiKey = apiKey; | ||
* | ||
* @param log - Log entry | ||
* @returns Promise<ILog> - resolves to the transformed log | ||
* @param message: string - Log message | ||
* @param level (LogLevel) - Level to log at (debug|info|warn|error) | ||
* @param log: (Partial<ITimberLog>) - Initial log (optional) | ||
* @returns Promise<ITimberLog> after syncing | ||
*/ | ||
async log(log) { | ||
async log(message, level = types_1.LogLevel.Info, log = {}) { | ||
// Check that we have a sync function | ||
@@ -81,4 +87,7 @@ if (typeof this._sync !== "function") { | ||
this._countLogged++; | ||
// Build the initial log | ||
const initialLog = Object.assign({ dt: new Date(), level, | ||
message }, log); | ||
// Pass the log through the middleware pipeline | ||
const transformedLog = await this._pipeline.reduceRight((fn, log) => fn.then(log), Promise.resolve(log)); | ||
const transformedLog = await this._middleware.reduceRight((fn, pipedLog) => fn.then(pipedLog), Promise.resolve(initialLog)); | ||
// Push the log through the batcher, and sync | ||
@@ -92,2 +101,46 @@ await this._batch(transformedLog); | ||
/** | ||
* | ||
* Debug level log, to be synced with Timber.io | ||
* | ||
* @param message: string - Log message | ||
* @param log: (Partial<ITimberLog>) - Initial log (optional) | ||
* @returns Promise<ITimberLog> after syncing | ||
*/ | ||
async debug(message, log = {}) { | ||
return this.log(message, types_1.LogLevel.Debug, log); | ||
} | ||
/** | ||
* | ||
* Info level log, to be synced with Timber.io | ||
* | ||
* @param message: string - Log message | ||
* @param log: (Partial<ITimberLog>) - Initial log (optional) | ||
* @returns Promise<ITimberLog> after syncing | ||
*/ | ||
async info(message, log = {}) { | ||
return this.log(message, types_1.LogLevel.Info, log); | ||
} | ||
/** | ||
* | ||
* Warning level log, to be synced with Timber.io | ||
* | ||
* @param message: string - Log message | ||
* @param log: (Partial<ITimberLog>) - Initial log (optional) | ||
* @returns Promise<ITimberLog> after syncing | ||
*/ | ||
async warn(message, log = {}) { | ||
return this.log(message, types_1.LogLevel.Warn, log); | ||
} | ||
/** | ||
* | ||
* Warning level log, to be synced with Timber.io | ||
* | ||
* @param message: string - Log message | ||
* @param log: (Partial<ITimberLog>) - Initial log (optional) | ||
* @returns Promise<ITimberLog> after syncing | ||
*/ | ||
async error(message, log = {}) { | ||
return this.log(message, types_1.LogLevel.Error, log); | ||
} | ||
/** | ||
* Sets the sync method - i.e. the final step in the pipeline to get logs | ||
@@ -108,3 +161,3 @@ * over to Timber.io | ||
use(fn) { | ||
this._pipeline.push(fn); | ||
this._middleware.push(fn); | ||
} | ||
@@ -118,3 +171,3 @@ /** | ||
remove(fn) { | ||
this._pipeline = this._pipeline.filter(p => p !== fn); | ||
this._middleware = this._middleware.filter(p => p !== fn); | ||
} | ||
@@ -121,0 +174,0 @@ } |
@@ -7,2 +7,3 @@ "use strict"; | ||
const base_1 = __importDefault(require("./base")); | ||
const types_1 = require("@timberio/types"); | ||
describe("base class tests", () => { | ||
@@ -16,23 +17,17 @@ it("should initialize with API key", () => { | ||
const base = new base_1.default("testing"); | ||
// Basic log | ||
const log = { | ||
message: "Test" | ||
}; | ||
// Expect logging to throw an error, since we're missing a `sync` func | ||
await expect(base.log(log)).rejects.toThrowError(/sync/); | ||
await expect(base.log("Test")).rejects.toThrowError(/sync/); | ||
}); | ||
it("should use the preProcess pipeline", async () => { | ||
// Fixtures | ||
const message = "Test"; | ||
const base = new base_1.default("testing"); | ||
// Add a mock sync method | ||
base.setSync(async (logs) => logs); | ||
// Basic log | ||
const log = { | ||
message: "Test" | ||
}; | ||
// Pass the log through the `.log()` function and get the result | ||
const result = await base.log(log); | ||
const result = await base.log(message); | ||
// Expect the message to be same | ||
expect(result.message).toEqual(log.message); | ||
expect(result.message).toEqual(message); | ||
// ... but a new `date` should be added | ||
expect(result.date).not.toBeUndefined(); | ||
expect(result.dt).not.toBeUndefined(); | ||
}); | ||
@@ -51,7 +46,3 @@ it("should default log count to zero", () => { | ||
base.setSync(async (log) => log); | ||
// Basic log | ||
const log = { | ||
message: "Test" | ||
}; | ||
void (await base.log(log)); | ||
void (await base.log("Test")); | ||
// Logged count should now be 1 | ||
@@ -70,8 +61,4 @@ expect(base.logged).toEqual(1); | ||
}); | ||
// Basic log | ||
const log = { | ||
message: "Test" | ||
}; | ||
// Fire the log event, and store the pending promise | ||
const pending = base.log(log); | ||
const pending = base.log("Test"); | ||
// The log count should be 1 | ||
@@ -87,9 +74,7 @@ expect(base.logged).toEqual(1); | ||
it("should add a pipeline function", async () => { | ||
// Fixtures | ||
const firstMessage = "First message"; | ||
const base = new base_1.default("testing"); | ||
// Add a mock sync method | ||
base.setSync(async (log) => log); | ||
// Initial log | ||
const log = { | ||
message: "First message" | ||
}; | ||
// Message to replacement with | ||
@@ -102,3 +87,3 @@ const newMessage = "Second message"; | ||
// Get the resulting log | ||
const result = await base.log(log); | ||
const result = await base.log(firstMessage); | ||
// The resulting message should equal the new message | ||
@@ -114,9 +99,64 @@ expect(result.message).toEqual(newMessage); | ||
// Confirm that it exists in the `_pipeline` array | ||
expect(base._pipeline).toContain(customPipeline); | ||
expect(base._middleware).toContain(customPipeline); | ||
// Remove the pipeline | ||
base.remove(customPipeline); | ||
// Confirm that it has disappeared from the array | ||
expect(base._pipeline).not.toContain(customPipeline); | ||
expect(base._middleware).not.toContain(customPipeline); | ||
}); | ||
it("should default to 'info' level logging", async () => { | ||
// Fixtures | ||
const message = "Test"; | ||
const base = new base_1.default("testing"); | ||
// Add a mock sync method | ||
base.setSync(async (log) => log); | ||
// Log | ||
const log = await base.log(message); | ||
// Should log at 'info' level | ||
expect(log.level).toEqual(types_1.LogLevel.Info); | ||
}); | ||
it("should handle 'debug' logging", async () => { | ||
// Fixtures | ||
const message = "Test"; | ||
const base = new base_1.default("testing"); | ||
// Add a mock sync method | ||
base.setSync(async (log) => log); | ||
// Log | ||
const log = await base.debug(message); | ||
// Should log at 'debug' level | ||
expect(log.level).toEqual(types_1.LogLevel.Debug); | ||
}); | ||
it("should handle 'info' logging", async () => { | ||
// Fixtures | ||
const message = "Test"; | ||
const base = new base_1.default("testing"); | ||
// Add a mock sync method | ||
base.setSync(async (log) => log); | ||
// Log | ||
const log = await base.info(message); | ||
// Should log at 'info' level | ||
expect(log.level).toEqual(types_1.LogLevel.Info); | ||
}); | ||
it("should handle 'warn' logging", async () => { | ||
// Fixtures | ||
const message = "Test"; | ||
const base = new base_1.default("testing"); | ||
// Add a mock sync method | ||
base.setSync(async (log) => log); | ||
// Log | ||
const log = await base.warn(message); | ||
// Should log at 'info' level | ||
expect(log.level).toEqual(types_1.LogLevel.Warn); | ||
}); | ||
it("should handle 'error' logging", async () => { | ||
// Fixtures | ||
const message = "Test"; | ||
const base = new base_1.default("testing"); | ||
// Add a mock sync method | ||
base.setSync(async (log) => log); | ||
// Log | ||
const log = await base.error(message); | ||
// Should log at 'info' level | ||
expect(log.level).toEqual(types_1.LogLevel.Error); | ||
}); | ||
}); | ||
//# sourceMappingURL=base.test.js.map |
@@ -1,3 +0,2 @@ | ||
import { ITimberLog, Middleware, ITimberOptions, Sync } from "@timberio/types"; | ||
import { preProcess } from "./pipeline"; | ||
import { ITimberLog, ITimberOptions, LogLevel, Middleware, Sync } from "@timberio/types"; | ||
/** | ||
@@ -10,3 +9,3 @@ * Timber core class for logging to the Timber.io service | ||
protected _batch: any; | ||
protected _pipeline: (typeof preProcess)[]; | ||
protected _middleware: Middleware[]; | ||
protected _sync?: Sync; | ||
@@ -37,7 +36,45 @@ private _countLogged; | ||
* | ||
* @param log - Log entry | ||
* @returns Promise<ILog> - resolves to the transformed log | ||
* @param message: string - Log message | ||
* @param level (LogLevel) - Level to log at (debug|info|warn|error) | ||
* @param log: (Partial<ITimberLog>) - Initial log (optional) | ||
* @returns Promise<ITimberLog> after syncing | ||
*/ | ||
log(log: ITimberLog): Promise<ITimberLog>; | ||
log(message: string, level?: LogLevel, log?: Partial<ITimberLog>): Promise<ITimberLog>; | ||
/** | ||
* | ||
* Debug level log, to be synced with Timber.io | ||
* | ||
* @param message: string - Log message | ||
* @param log: (Partial<ITimberLog>) - Initial log (optional) | ||
* @returns Promise<ITimberLog> after syncing | ||
*/ | ||
debug(message: string, log?: Partial<ITimberLog>): Promise<ITimberLog>; | ||
/** | ||
* | ||
* Info level log, to be synced with Timber.io | ||
* | ||
* @param message: string - Log message | ||
* @param log: (Partial<ITimberLog>) - Initial log (optional) | ||
* @returns Promise<ITimberLog> after syncing | ||
*/ | ||
info(message: string, log?: Partial<ITimberLog>): Promise<ITimberLog>; | ||
/** | ||
* | ||
* Warning level log, to be synced with Timber.io | ||
* | ||
* @param message: string - Log message | ||
* @param log: (Partial<ITimberLog>) - Initial log (optional) | ||
* @returns Promise<ITimberLog> after syncing | ||
*/ | ||
warn(message: string, log?: Partial<ITimberLog>): Promise<ITimberLog>; | ||
/** | ||
* | ||
* Warning level log, to be synced with Timber.io | ||
* | ||
* @param message: string - Log message | ||
* @param log: (Partial<ITimberLog>) - Initial log (optional) | ||
* @returns Promise<ITimberLog> after syncing | ||
*/ | ||
error(message: string, log?: Partial<ITimberLog>): Promise<ITimberLog>; | ||
/** | ||
* Sets the sync method - i.e. the final step in the pipeline to get logs | ||
@@ -44,0 +81,0 @@ * over to Timber.io |
@@ -0,7 +1,7 @@ | ||
import { LogLevel } from "@timberio/types"; | ||
import { makeBatch, makeThrottle } from "@timberio/tools"; | ||
import { preProcess } from "./pipeline"; | ||
// Set default options for Timber | ||
const defaultOptions = { | ||
// Maximum number of logs to sync in a single request to Timber.io | ||
batchSize: 10, | ||
batchSize: 1000, | ||
// Max interval (in milliseconds) before a batch of logs proceeds to syncing | ||
@@ -24,4 +24,4 @@ batchInterval: 1000, | ||
constructor(apiKey, options) { | ||
// Transform pipeline | ||
this._pipeline = [preProcess]; | ||
// Middleware | ||
this._middleware = []; | ||
// Number of logs logged | ||
@@ -31,2 +31,6 @@ this._countLogged = 0; | ||
this._countSynced = 0; | ||
// First, check we have a valid API key | ||
if (typeof apiKey !== "string" || apiKey === "") { | ||
throw new Error("Timber API key missing"); | ||
} | ||
// Store the API key, to use for syncing with Timber.io | ||
@@ -68,6 +72,8 @@ this._apiKey = apiKey; | ||
* | ||
* @param log - Log entry | ||
* @returns Promise<ILog> - resolves to the transformed log | ||
* @param message: string - Log message | ||
* @param level (LogLevel) - Level to log at (debug|info|warn|error) | ||
* @param log: (Partial<ITimberLog>) - Initial log (optional) | ||
* @returns Promise<ITimberLog> after syncing | ||
*/ | ||
async log(log) { | ||
async log(message, level = LogLevel.Info, log = {}) { | ||
// Check that we have a sync function | ||
@@ -79,4 +85,7 @@ if (typeof this._sync !== "function") { | ||
this._countLogged++; | ||
// Build the initial log | ||
const initialLog = Object.assign({ dt: new Date(), level, | ||
message }, log); | ||
// Pass the log through the middleware pipeline | ||
const transformedLog = await this._pipeline.reduceRight((fn, log) => fn.then(log), Promise.resolve(log)); | ||
const transformedLog = await this._middleware.reduceRight((fn, pipedLog) => fn.then(pipedLog), Promise.resolve(initialLog)); | ||
// Push the log through the batcher, and sync | ||
@@ -90,2 +99,46 @@ await this._batch(transformedLog); | ||
/** | ||
* | ||
* Debug level log, to be synced with Timber.io | ||
* | ||
* @param message: string - Log message | ||
* @param log: (Partial<ITimberLog>) - Initial log (optional) | ||
* @returns Promise<ITimberLog> after syncing | ||
*/ | ||
async debug(message, log = {}) { | ||
return this.log(message, LogLevel.Debug, log); | ||
} | ||
/** | ||
* | ||
* Info level log, to be synced with Timber.io | ||
* | ||
* @param message: string - Log message | ||
* @param log: (Partial<ITimberLog>) - Initial log (optional) | ||
* @returns Promise<ITimberLog> after syncing | ||
*/ | ||
async info(message, log = {}) { | ||
return this.log(message, LogLevel.Info, log); | ||
} | ||
/** | ||
* | ||
* Warning level log, to be synced with Timber.io | ||
* | ||
* @param message: string - Log message | ||
* @param log: (Partial<ITimberLog>) - Initial log (optional) | ||
* @returns Promise<ITimberLog> after syncing | ||
*/ | ||
async warn(message, log = {}) { | ||
return this.log(message, LogLevel.Warn, log); | ||
} | ||
/** | ||
* | ||
* Warning level log, to be synced with Timber.io | ||
* | ||
* @param message: string - Log message | ||
* @param log: (Partial<ITimberLog>) - Initial log (optional) | ||
* @returns Promise<ITimberLog> after syncing | ||
*/ | ||
async error(message, log = {}) { | ||
return this.log(message, LogLevel.Error, log); | ||
} | ||
/** | ||
* Sets the sync method - i.e. the final step in the pipeline to get logs | ||
@@ -106,3 +159,3 @@ * over to Timber.io | ||
use(fn) { | ||
this._pipeline.push(fn); | ||
this._middleware.push(fn); | ||
} | ||
@@ -116,3 +169,3 @@ /** | ||
remove(fn) { | ||
this._pipeline = this._pipeline.filter(p => p !== fn); | ||
this._middleware = this._middleware.filter(p => p !== fn); | ||
} | ||
@@ -119,0 +172,0 @@ } |
import Base from "./base"; | ||
import { LogLevel } from "@timberio/types"; | ||
describe("base class tests", () => { | ||
@@ -10,23 +11,17 @@ it("should initialize with API key", () => { | ||
const base = new Base("testing"); | ||
// Basic log | ||
const log = { | ||
message: "Test" | ||
}; | ||
// Expect logging to throw an error, since we're missing a `sync` func | ||
await expect(base.log(log)).rejects.toThrowError(/sync/); | ||
await expect(base.log("Test")).rejects.toThrowError(/sync/); | ||
}); | ||
it("should use the preProcess pipeline", async () => { | ||
// Fixtures | ||
const message = "Test"; | ||
const base = new Base("testing"); | ||
// Add a mock sync method | ||
base.setSync(async (logs) => logs); | ||
// Basic log | ||
const log = { | ||
message: "Test" | ||
}; | ||
// Pass the log through the `.log()` function and get the result | ||
const result = await base.log(log); | ||
const result = await base.log(message); | ||
// Expect the message to be same | ||
expect(result.message).toEqual(log.message); | ||
expect(result.message).toEqual(message); | ||
// ... but a new `date` should be added | ||
expect(result.date).not.toBeUndefined(); | ||
expect(result.dt).not.toBeUndefined(); | ||
}); | ||
@@ -45,7 +40,3 @@ it("should default log count to zero", () => { | ||
base.setSync(async (log) => log); | ||
// Basic log | ||
const log = { | ||
message: "Test" | ||
}; | ||
void (await base.log(log)); | ||
void (await base.log("Test")); | ||
// Logged count should now be 1 | ||
@@ -64,8 +55,4 @@ expect(base.logged).toEqual(1); | ||
}); | ||
// Basic log | ||
const log = { | ||
message: "Test" | ||
}; | ||
// Fire the log event, and store the pending promise | ||
const pending = base.log(log); | ||
const pending = base.log("Test"); | ||
// The log count should be 1 | ||
@@ -81,9 +68,7 @@ expect(base.logged).toEqual(1); | ||
it("should add a pipeline function", async () => { | ||
// Fixtures | ||
const firstMessage = "First message"; | ||
const base = new Base("testing"); | ||
// Add a mock sync method | ||
base.setSync(async (log) => log); | ||
// Initial log | ||
const log = { | ||
message: "First message" | ||
}; | ||
// Message to replacement with | ||
@@ -96,3 +81,3 @@ const newMessage = "Second message"; | ||
// Get the resulting log | ||
const result = await base.log(log); | ||
const result = await base.log(firstMessage); | ||
// The resulting message should equal the new message | ||
@@ -108,9 +93,64 @@ expect(result.message).toEqual(newMessage); | ||
// Confirm that it exists in the `_pipeline` array | ||
expect(base._pipeline).toContain(customPipeline); | ||
expect(base._middleware).toContain(customPipeline); | ||
// Remove the pipeline | ||
base.remove(customPipeline); | ||
// Confirm that it has disappeared from the array | ||
expect(base._pipeline).not.toContain(customPipeline); | ||
expect(base._middleware).not.toContain(customPipeline); | ||
}); | ||
it("should default to 'info' level logging", async () => { | ||
// Fixtures | ||
const message = "Test"; | ||
const base = new Base("testing"); | ||
// Add a mock sync method | ||
base.setSync(async (log) => log); | ||
// Log | ||
const log = await base.log(message); | ||
// Should log at 'info' level | ||
expect(log.level).toEqual(LogLevel.Info); | ||
}); | ||
it("should handle 'debug' logging", async () => { | ||
// Fixtures | ||
const message = "Test"; | ||
const base = new Base("testing"); | ||
// Add a mock sync method | ||
base.setSync(async (log) => log); | ||
// Log | ||
const log = await base.debug(message); | ||
// Should log at 'debug' level | ||
expect(log.level).toEqual(LogLevel.Debug); | ||
}); | ||
it("should handle 'info' logging", async () => { | ||
// Fixtures | ||
const message = "Test"; | ||
const base = new Base("testing"); | ||
// Add a mock sync method | ||
base.setSync(async (log) => log); | ||
// Log | ||
const log = await base.info(message); | ||
// Should log at 'info' level | ||
expect(log.level).toEqual(LogLevel.Info); | ||
}); | ||
it("should handle 'warn' logging", async () => { | ||
// Fixtures | ||
const message = "Test"; | ||
const base = new Base("testing"); | ||
// Add a mock sync method | ||
base.setSync(async (log) => log); | ||
// Log | ||
const log = await base.warn(message); | ||
// Should log at 'info' level | ||
expect(log.level).toEqual(LogLevel.Warn); | ||
}); | ||
it("should handle 'error' logging", async () => { | ||
// Fixtures | ||
const message = "Test"; | ||
const base = new Base("testing"); | ||
// Add a mock sync method | ||
base.setSync(async (log) => log); | ||
// Log | ||
const log = await base.error(message); | ||
// Should log at 'info' level | ||
expect(log.level).toEqual(LogLevel.Error); | ||
}); | ||
}); | ||
//# sourceMappingURL=base.test.js.map |
{ | ||
"name": "@timberio/core", | ||
"version": "0.15.0", | ||
"version": "0.16.0", | ||
"description": "Timber.io - logging core", | ||
@@ -40,6 +40,6 @@ "keywords": [ | ||
"dependencies": { | ||
"@timberio/tools": "^0.15.0", | ||
"@timberio/types": "^0.15.0" | ||
"@timberio/tools": "^0.16.0", | ||
"@timberio/types": "^0.16.0" | ||
}, | ||
"gitHead": "b7cd2447a5d4829e632b656d156a1e98716dd5a0" | ||
"gitHead": "13fe691283afc3d96d5bc1ff7b13173f55389621" | ||
} |
import Base from "./base"; | ||
import { ITimberLog } from "@timberio/types"; | ||
import { ITimberLog, LogLevel } from "@timberio/types"; | ||
@@ -15,12 +15,9 @@ describe("base class tests", () => { | ||
// Basic log | ||
const log = { | ||
message: "Test" | ||
}; | ||
// Expect logging to throw an error, since we're missing a `sync` func | ||
await expect(base.log(log)).rejects.toThrowError(/sync/); | ||
await expect(base.log("Test")).rejects.toThrowError(/sync/); | ||
}); | ||
it("should use the preProcess pipeline", async () => { | ||
// Fixtures | ||
const message = "Test"; | ||
const base = new Base("testing"); | ||
@@ -31,15 +28,10 @@ | ||
// Basic log | ||
const log = { | ||
message: "Test" | ||
}; | ||
// Pass the log through the `.log()` function and get the result | ||
const result = await base.log(log); | ||
const result = await base.log(message); | ||
// Expect the message to be same | ||
expect(result.message).toEqual(log.message); | ||
expect(result.message).toEqual(message); | ||
// ... but a new `date` should be added | ||
expect(result.date).not.toBeUndefined(); | ||
expect(result.dt).not.toBeUndefined(); | ||
}); | ||
@@ -65,9 +57,4 @@ | ||
// Basic log | ||
const log = { | ||
message: "Test" | ||
}; | ||
void (await base.log("Test")); | ||
void (await base.log(log)); | ||
// Logged count should now be 1 | ||
@@ -89,9 +76,4 @@ expect(base.logged).toEqual(1); | ||
// Basic log | ||
const log = { | ||
message: "Test" | ||
}; | ||
// Fire the log event, and store the pending promise | ||
const pending = base.log(log); | ||
const pending = base.log("Test"); | ||
@@ -112,2 +94,4 @@ // The log count should be 1 | ||
it("should add a pipeline function", async () => { | ||
// Fixtures | ||
const firstMessage = "First message"; | ||
const base = new Base("testing"); | ||
@@ -118,7 +102,2 @@ | ||
// Initial log | ||
const log = { | ||
message: "First message" | ||
}; | ||
// Message to replacement with | ||
@@ -136,3 +115,3 @@ const newMessage = "Second message"; | ||
// Get the resulting log | ||
const result = await base.log(log); | ||
const result = await base.log(firstMessage); | ||
@@ -153,3 +132,3 @@ // The resulting message should equal the new message | ||
// Confirm that it exists in the `_pipeline` array | ||
expect((base as any)._pipeline).toContain(customPipeline); | ||
expect((base as any)._middleware).toContain(customPipeline); | ||
@@ -160,4 +139,79 @@ // Remove the pipeline | ||
// Confirm that it has disappeared from the array | ||
expect((base as any)._pipeline).not.toContain(customPipeline); | ||
expect((base as any)._middleware).not.toContain(customPipeline); | ||
}); | ||
it("should default to 'info' level logging", async () => { | ||
// Fixtures | ||
const message = "Test"; | ||
const base = new Base("testing"); | ||
// Add a mock sync method | ||
base.setSync(async log => log); | ||
// Log | ||
const log = await base.log(message); | ||
// Should log at 'info' level | ||
expect(log.level).toEqual(LogLevel.Info); | ||
}); | ||
it("should handle 'debug' logging", async () => { | ||
// Fixtures | ||
const message = "Test"; | ||
const base = new Base("testing"); | ||
// Add a mock sync method | ||
base.setSync(async log => log); | ||
// Log | ||
const log = await base.debug(message); | ||
// Should log at 'debug' level | ||
expect(log.level).toEqual(LogLevel.Debug); | ||
}); | ||
it("should handle 'info' logging", async () => { | ||
// Fixtures | ||
const message = "Test"; | ||
const base = new Base("testing"); | ||
// Add a mock sync method | ||
base.setSync(async log => log); | ||
// Log | ||
const log = await base.info(message); | ||
// Should log at 'info' level | ||
expect(log.level).toEqual(LogLevel.Info); | ||
}); | ||
it("should handle 'warn' logging", async () => { | ||
// Fixtures | ||
const message = "Test"; | ||
const base = new Base("testing"); | ||
// Add a mock sync method | ||
base.setSync(async log => log); | ||
// Log | ||
const log = await base.warn(message); | ||
// Should log at 'info' level | ||
expect(log.level).toEqual(LogLevel.Warn); | ||
}); | ||
it("should handle 'error' logging", async () => { | ||
// Fixtures | ||
const message = "Test"; | ||
const base = new Base("testing"); | ||
// Add a mock sync method | ||
base.setSync(async log => log); | ||
// Log | ||
const log = await base.error(message); | ||
// Should log at 'info' level | ||
expect(log.level).toEqual(LogLevel.Error); | ||
}); | ||
}); |
111
src/base.ts
@@ -1,10 +0,14 @@ | ||
import { ITimberLog, Middleware, ITimberOptions, Sync } from "@timberio/types"; | ||
import { | ||
ITimberLog, | ||
ITimberOptions, | ||
LogLevel, | ||
Middleware, | ||
Sync | ||
} from "@timberio/types"; | ||
import { makeBatch, makeThrottle } from "@timberio/tools"; | ||
import { preProcess } from "./pipeline"; | ||
// Set default options for Timber | ||
const defaultOptions: ITimberOptions = { | ||
// Maximum number of logs to sync in a single request to Timber.io | ||
batchSize: 10, | ||
batchSize: 1000, | ||
@@ -31,4 +35,4 @@ // Max interval (in milliseconds) before a batch of logs proceeds to syncing | ||
// Transform pipeline | ||
protected _pipeline = [preProcess]; | ||
// Middleware | ||
protected _middleware: Middleware[] = []; | ||
@@ -53,2 +57,7 @@ // Sync function | ||
public constructor(apiKey: string, options?: Partial<ITimberOptions>) { | ||
// First, check we have a valid API key | ||
if (typeof apiKey !== "string" || apiKey === "") { | ||
throw new Error("Timber API key missing"); | ||
} | ||
// Store the API key, to use for syncing with Timber.io | ||
@@ -102,6 +111,12 @@ this._apiKey = apiKey; | ||
* | ||
* @param log - Log entry | ||
* @returns Promise<ILog> - resolves to the transformed log | ||
* @param message: string - Log message | ||
* @param level (LogLevel) - Level to log at (debug|info|warn|error) | ||
* @param log: (Partial<ITimberLog>) - Initial log (optional) | ||
* @returns Promise<ITimberLog> after syncing | ||
*/ | ||
public async log(log: ITimberLog): Promise<ITimberLog> { | ||
public async log( | ||
message: string, | ||
level: LogLevel = LogLevel.Info, | ||
log: Partial<ITimberLog> = {} | ||
): Promise<ITimberLog> { | ||
// Check that we have a sync function | ||
@@ -115,6 +130,14 @@ if (typeof this._sync !== "function") { | ||
// Build the initial log | ||
const initialLog: ITimberLog = { | ||
dt: new Date(), | ||
level, | ||
message, | ||
...log | ||
}; | ||
// Pass the log through the middleware pipeline | ||
const transformedLog = await this._pipeline.reduceRight( | ||
(fn, log) => fn.then(log), | ||
Promise.resolve(log) | ||
const transformedLog = await this._middleware.reduceRight( | ||
(fn, pipedLog) => fn.then(pipedLog), | ||
Promise.resolve(initialLog) | ||
); | ||
@@ -133,2 +156,62 @@ | ||
/** | ||
* | ||
* Debug level log, to be synced with Timber.io | ||
* | ||
* @param message: string - Log message | ||
* @param log: (Partial<ITimberLog>) - Initial log (optional) | ||
* @returns Promise<ITimberLog> after syncing | ||
*/ | ||
public async debug( | ||
message: string, | ||
log: Partial<ITimberLog> = {} | ||
): Promise<ITimberLog> { | ||
return this.log(message, LogLevel.Debug, log); | ||
} | ||
/** | ||
* | ||
* Info level log, to be synced with Timber.io | ||
* | ||
* @param message: string - Log message | ||
* @param log: (Partial<ITimberLog>) - Initial log (optional) | ||
* @returns Promise<ITimberLog> after syncing | ||
*/ | ||
public async info( | ||
message: string, | ||
log: Partial<ITimberLog> = {} | ||
): Promise<ITimberLog> { | ||
return this.log(message, LogLevel.Info, log); | ||
} | ||
/** | ||
* | ||
* Warning level log, to be synced with Timber.io | ||
* | ||
* @param message: string - Log message | ||
* @param log: (Partial<ITimberLog>) - Initial log (optional) | ||
* @returns Promise<ITimberLog> after syncing | ||
*/ | ||
public async warn( | ||
message: string, | ||
log: Partial<ITimberLog> = {} | ||
): Promise<ITimberLog> { | ||
return this.log(message, LogLevel.Warn, log); | ||
} | ||
/** | ||
* | ||
* Warning level log, to be synced with Timber.io | ||
* | ||
* @param message: string - Log message | ||
* @param log: (Partial<ITimberLog>) - Initial log (optional) | ||
* @returns Promise<ITimberLog> after syncing | ||
*/ | ||
public async error( | ||
message: string, | ||
log: Partial<ITimberLog> = {} | ||
): Promise<ITimberLog> { | ||
return this.log(message, LogLevel.Error, log); | ||
} | ||
/** | ||
* Sets the sync method - i.e. the final step in the pipeline to get logs | ||
@@ -150,3 +233,3 @@ * over to Timber.io | ||
public use(fn: Middleware): void { | ||
this._pipeline.push(fn); | ||
this._middleware.push(fn); | ||
} | ||
@@ -161,3 +244,3 @@ | ||
public remove(fn: Middleware): void { | ||
this._pipeline = this._pipeline.filter(p => p !== fn); | ||
this._middleware = this._middleware.filter(p => p !== fn); | ||
} | ||
@@ -164,0 +247,0 @@ } |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
67100
1303
36
+ Added@timberio/tools@0.16.0(transitive)
+ Added@timberio/types@0.16.0(transitive)
- Removed@timberio/tools@0.15.0(transitive)
- Removed@timberio/types@0.15.0(transitive)
Updated@timberio/tools@^0.16.0
Updated@timberio/types@^0.16.0