Comparing version 3.0.0 to 3.1.0
# Changelog | ||
### 3.1.0 (2024-04-21) | ||
- Feature | ||
- Add GCP Cloud Logger service | ||
### 3.0.0 (2023-11-21) | ||
@@ -4,0 +9,0 @@ |
@@ -0,4 +1,6 @@ | ||
import { getLoggerService } from './utils'; | ||
import { LaLogOptions, LevelType, LogData, LogFunction, LogPresets, ParseReqIn, ParseReqOut, ResponseWrapper, TimeLogFunction } from './local-types'; | ||
export * from './local-types'; | ||
export default class Logger { | ||
loggerServices: ReturnType<typeof getLoggerService>[]; | ||
isTransient: boolean; | ||
@@ -5,0 +7,0 @@ logCollector: any[] | null; |
@@ -30,3 +30,2 @@ "use strict"; | ||
const utils_1 = require("./utils"); | ||
const loggly_wrapper_1 = require("./loggly-wrapper"); | ||
const local_types_1 = require("./local-types"); | ||
@@ -45,6 +44,7 @@ __exportStar(require("./local-types"), exports); | ||
constructor(options) { | ||
const { addTrackId, moduleName, presets, serviceName, isTransient, } = options; | ||
const { addTrackId, isTransient, loggerServices, moduleName, presets, serviceName, } = options; | ||
this.isTransient = !!isTransient; | ||
this.logCollector = isTransient ? [] : null; | ||
this.presets = Object.assign({ module: moduleName }, ((0, utils_1.isObject)(presets) ? presets : {})); | ||
this.loggerServices = (loggerServices || ['loggly']).map(utils_1.getLoggerService); | ||
if (addTrackId && !this.presets.trackId) { | ||
@@ -193,3 +193,4 @@ this.presets.trackId = (0, crypto_1.randomUUID)(); | ||
this.isTransientTriggered = true; | ||
await (0, loggly_wrapper_1.logBatch)({ logObj: this.logCollector, tag: this.tag }); | ||
const loggingObject = { logObj: this.logCollector, tag: this.tag }; | ||
await Promise.all(this.loggerServices.map((loggerService) => loggerService.logBatch(loggingObject))); | ||
this.logCollector = null; // Can GC right away now that this array is no longer needed | ||
@@ -199,3 +200,4 @@ } | ||
else { | ||
return (0, loggly_wrapper_1.logSingle)({ logObj, tag: this.tag }); | ||
const loggingObject = { logObj, tag: this.tag }; | ||
await Promise.all(this.loggerServices.map((loggerService) => loggerService.logSingle(loggingObject))); | ||
} | ||
@@ -202,0 +204,0 @@ } |
@@ -11,2 +11,4 @@ import { Request, Response } from 'express'; | ||
} | ||
declare const loggerServices: readonly ["loggly", "gcp"]; | ||
export type LoggerService = typeof loggerServices[number]; | ||
export interface LaLogOptions { | ||
@@ -18,2 +20,3 @@ addTrackId?: boolean; | ||
isTransient?: boolean; | ||
loggerServices?: LoggerService[]; | ||
} | ||
@@ -49,1 +52,2 @@ export type ParseReqIn = Request & { | ||
}; | ||
export {}; |
@@ -5,2 +5,3 @@ "use strict"; | ||
exports.levels = ['trace', 'info', 'warn', 'error', 'fatal', 'security']; | ||
const loggerServices = ['loggly', 'gcp']; | ||
//# sourceMappingURL=local-types.js.map |
@@ -1,2 +0,2 @@ | ||
import { logDataEnriched, LogDataOut } from './local-types'; | ||
import { logDataEnriched, LogDataOut, LoggerService } from './local-types'; | ||
export declare const isObject: (obj?: Record<string, unknown> | null) => boolean; | ||
@@ -9,1 +9,17 @@ export declare const safeJsonStringify: (obj: Record<string, unknown>) => string; | ||
export declare const enrichError: (body: LogDataOut) => logDataEnriched | LogDataOut; | ||
export interface LogBatchOptions { | ||
tag: string; | ||
logglyToken?: string; | ||
logObj: any[]; | ||
} | ||
export type LogBatch = (options: LogBatchOptions) => Promise<Record<string, unknown> | void>; | ||
export interface LogSingleOptions { | ||
tag: string; | ||
logglyToken?: string; | ||
logObj: any; | ||
} | ||
export type LogSingle = (options: LogSingleOptions) => Promise<Record<string, unknown> | void>; | ||
export declare const getLoggerService: (loggerService: LoggerService) => { | ||
logBatch: LogBatch; | ||
logSingle: LogSingle; | ||
}; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.enrichError = exports.safeJsonStringify = exports.isObject = void 0; | ||
exports.getLoggerService = exports.enrichError = exports.safeJsonStringify = exports.isObject = void 0; | ||
const loggly_wrapper_1 = require("./loggly/loggly-wrapper"); | ||
const gcp_wrapper_copy_1 = require("./gcp/gcp-wrapper-copy"); | ||
const isObject = (obj) => !!obj && obj.toString() === '[object Object]' && !Array.isArray(obj); | ||
@@ -52,2 +54,13 @@ exports.isObject = isObject; | ||
exports.enrichError = enrichError; | ||
const getLoggerService = (loggerService) => { | ||
switch (loggerService) { | ||
case 'gcp': | ||
return gcp_wrapper_copy_1.gcpLoggers; | ||
case 'loggly': | ||
return loggly_wrapper_1.logglyLoggers; | ||
default: | ||
throw new Error('invalid logger service'); | ||
} | ||
}; | ||
exports.getLoggerService = getLoggerService; | ||
//# sourceMappingURL=utils.js.map |
import { randomUUID } from 'crypto'; | ||
import { enrichError, isObject } from './utils'; | ||
import { | ||
enrichError, getLoggerService, isObject, LogBatchOptions, LogSingleOptions, | ||
} from './utils'; | ||
import { | ||
logBatch, | ||
logSingle, | ||
} from './loggly-wrapper'; | ||
import { | ||
LaLogOptions, levels, LevelType, LogData, logDataEnriched, LogDataOut, LogFunction, | ||
@@ -28,2 +26,4 @@ LogPresets, ParseReqIn, ParseReqOut, ResponseWrapper, TimeLogFunction, | ||
export default class Logger { | ||
loggerServices: ReturnType<typeof getLoggerService>[]; | ||
isTransient: boolean; | ||
@@ -60,6 +60,7 @@ | ||
addTrackId, | ||
isTransient, | ||
loggerServices, | ||
moduleName, | ||
presets, | ||
serviceName, | ||
isTransient, | ||
} = options; | ||
@@ -76,2 +77,4 @@ | ||
this.loggerServices = (loggerServices || [{ type: 'loggly' }]).map(getLoggerService); | ||
if (addTrackId && !this.presets.trackId) { | ||
@@ -246,7 +249,13 @@ this.presets.trackId = randomUUID(); | ||
this.isTransientTriggered = true; | ||
await logBatch({ logObj: this.logCollector, tag: this.tag }); | ||
const loggingObject: LogBatchOptions = { logObj: this.logCollector, tag: this.tag }; | ||
await Promise.all(this.loggerServices.map( | ||
(loggerService) => loggerService.logBatch(loggingObject), | ||
)); | ||
this.logCollector = null; // Can GC right away now that this array is no longer needed | ||
} | ||
} else { | ||
return logSingle({ logObj, tag: this.tag }); | ||
const loggingObject: LogSingleOptions = { logObj, tag: this.tag }; | ||
await Promise.all(this.loggerServices.map( | ||
(loggerService) => loggerService.logSingle(loggingObject), | ||
)); | ||
} | ||
@@ -253,0 +262,0 @@ } |
@@ -10,13 +10,28 @@ import { Request, Response } from 'express'; | ||
export interface LogPresets extends Record<string, unknown> { | ||
module?: string; | ||
trackId?: string; | ||
} | ||
module?: string; | ||
trackId?: string; | ||
} | ||
export interface GcpLoggerService { | ||
email: string; | ||
key: string; | ||
projectId: string; | ||
type: 'gcp'; | ||
} | ||
export interface LogglyLoggerService { | ||
logglyToken?: string; | ||
type: 'loggly'; | ||
} | ||
export type LoggerService = GcpLoggerService | LogglyLoggerService; | ||
export interface LaLogOptions { | ||
addTrackId?: boolean; | ||
moduleName?: string; | ||
presets?: LogPresets; | ||
serviceName?: string; | ||
isTransient?: boolean; | ||
} | ||
addTrackId?: boolean; | ||
isTransient?: boolean; | ||
loggerServices?: LoggerService[]; | ||
moduleName?: string; | ||
presets?: LogPresets; | ||
serviceName?: string; | ||
} | ||
@@ -23,0 +38,0 @@ export type ParseReqIn = Request & { user?: unknown }; |
@@ -1,2 +0,4 @@ | ||
import { logDataEnriched, LogDataOut } from './local-types'; | ||
import { logDataEnriched, LogDataOut, LoggerService } from './local-types'; | ||
import { logglyLoggers } from './loggly/loggly-wrapper'; | ||
import { gcpLoggers } from './gcp/gcp-wrapper'; | ||
@@ -66,1 +68,30 @@ export const isObject = ( | ||
}; | ||
export interface LogBatchOptions { | ||
tag: string; | ||
logglyToken?: string; | ||
logObj: any[]; | ||
} | ||
export type LogBatch = ( | ||
options: LogBatchOptions, | ||
) => Promise<Record<string, unknown> | void>; | ||
export interface LogSingleOptions { | ||
tag: string; | ||
logglyToken?: string; | ||
logObj: any; | ||
} | ||
export type LogSingle = ( | ||
options: LogSingleOptions, | ||
) => Promise<Record<string, unknown> | void>; | ||
export const getLoggerService = (loggerService: LoggerService) => { | ||
switch (loggerService.type) { | ||
case 'gcp': | ||
return gcpLoggers(loggerService); | ||
case 'loggly': | ||
return logglyLoggers(loggerService); | ||
default: | ||
throw new Error('invalid logger service'); | ||
} | ||
}; |
@@ -7,2 +7,3 @@ { | ||
"dependencies": { | ||
"google-auth-library": "9.8.0", | ||
"node-fetch": "2.7.0" | ||
@@ -13,11 +14,11 @@ }, | ||
"@types/express": "4.17.21", | ||
"@types/jest": "29.5.9", | ||
"@types/node": "20.9.3", | ||
"@types/jest": "29.5.12", | ||
"@types/node": "20.12.7", | ||
"@types/node-fetch": "2.6.9", | ||
"@typescript-eslint/eslint-plugin": "5.61.0", | ||
"@typescript-eslint/eslint-plugin": "5.62.0", | ||
"@typescript-eslint/parser": "5.62.0", | ||
"eslint": "8.54.0", | ||
"eslint": "8.57.0", | ||
"eslint-config-airbnb-base": "15.0.0", | ||
"eslint-plugin-import": "2.29.0", | ||
"eslint-plugin-jest": "27.6.0", | ||
"eslint-plugin-import": "2.29.1", | ||
"eslint-plugin-jest": "27.9.0", | ||
"eslint-plugin-security": "1.7.1", | ||
@@ -27,4 +28,5 @@ "eslint-plugin-sort-keys-fix": "1.1.2", | ||
"pre-commit": "1.2.2", | ||
"ts-jest": "29.1.1", | ||
"typescript": "5.3.2" | ||
"ts-jest": "29.1.2", | ||
"ts-node": "10.9.2", | ||
"typescript": "5.4.5" | ||
}, | ||
@@ -58,3 +60,3 @@ "homepage": "https://github.com/guyellis/lalog#readme", | ||
"types": "dist/index.d.ts", | ||
"version": "3.0.0" | ||
"version": "3.1.0" | ||
} |
@@ -50,6 +50,8 @@ # lalog | ||
const logger = Logger.create({ | ||
addTrackId: true, // optional - defaults to false | ||
isTransient: true, // optional - defaults to false | ||
loggerServices: [/* see examples */], | ||
moduleName: 'module-name', | ||
presets: {}, // optional - defaults to empty object if missing or not a valid object | ||
serviceName: 'service-name', | ||
moduleName: 'module-name', | ||
presets: {}, // optional | ||
addTrackId: true, // options | ||
}); | ||
@@ -62,15 +64,19 @@ ``` | ||
const logger = new Logger({ | ||
serviceName: 'service-name', | ||
addTrackId: true, // optional - defaults to false | ||
isTransient: true, // optional - defaults to false | ||
loggerServices: [/* see examples */], | ||
moduleName: 'module-name', | ||
presets: {}, // optional - defaults to empty object if missing or not a valid object | ||
addTrackId: true, // optional - defaults to false | ||
isTransient: true, // optional - defaults to false | ||
serviceName: 'service-name', | ||
}); | ||
``` | ||
Notes on create: | ||
Notes on create options: | ||
- `presets` is an optional object that will have its contents merged with any object that's logged. Useful for putting in data that you want logged with every message. | ||
#### `addTrackId` | ||
- If `addTrackId` is truthy then a `trackId` (uuid) will be added to `presets`. | ||
- The `moduleName` is added to `presets` as `module`. | ||
#### `isTransient` | ||
- If `isTransient` is set to true then all calls to logger will be saved and written in batch mode, in | ||
@@ -83,3 +89,3 @@ sequence, to the destination if any of the log calls triggers a write. This flag is called `isTransient` | ||
happened before the `error()` was called. The `isTransient` flag causes the logger to store all of | ||
those logs and write then in this scenario. | ||
those logs and write them in this scenario. | ||
- More notes on `isTransient` | ||
@@ -94,2 +100,44 @@ - You would almost always want to also set `trackId` to `true` when you set `isTransient` to `true` | ||
#### `loggerServices` | ||
To keep this backward compatible, `loggerServices defaults to: | ||
```javascript | ||
[{ | ||
type: 'loggly' | ||
}] | ||
``` | ||
This maintains the original Loggly functionality as it was. | ||
If specified, this should be a 1 or 2 element array with one or both of these schemas: | ||
```typescript | ||
export interface GcpLoggerService { | ||
email: string; | ||
key: string; | ||
projectId: string; | ||
type: 'gcp'; | ||
} | ||
export interface LogglyLoggerService { | ||
logglyToken?: string; | ||
type: 'loggly'; | ||
} | ||
``` | ||
For the GCP Cloud Logging service you will need to follow the ideas in the [GCP Cloud Logging](docs/gcp-cloud-logging.md) guide to set these values up. | ||
#### `moduleName` | ||
- The `moduleName` is added to `presets` as `module`. | ||
#### `presets` | ||
- `presets` is an optional object that will have its contents merged with any object that's logged. Useful for putting in data that you want logged with every message. | ||
#### `serviceName` | ||
- The `serviceName` is recorded with the log | ||
### Write Log Messages | ||
@@ -96,0 +144,0 @@ |
@@ -18,3 +18,4 @@ { | ||
"include": [ | ||
"lib/**/*" | ||
"lib/**/*", | ||
"gcp-testing/gcp-tester.ts" | ||
], | ||
@@ -21,0 +22,0 @@ "exclude": [ |
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
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
429962
66
2155
198
2
17
8
1
+ Addedgoogle-auth-library@9.8.0
+ Addedagent-base@7.1.3(transitive)
+ Addedbase64-js@1.5.1(transitive)
+ Addedbignumber.js@9.1.2(transitive)
+ Addedbuffer-equal-constant-time@1.0.1(transitive)
+ Addeddebug@4.4.0(transitive)
+ Addedecdsa-sig-formatter@1.0.11(transitive)
+ Addedextend@3.0.2(transitive)
+ Addedgaxios@6.7.1(transitive)
+ Addedgcp-metadata@6.1.0(transitive)
+ Addedgoogle-auth-library@9.8.0(transitive)
+ Addedgtoken@7.1.0(transitive)
+ Addedhttps-proxy-agent@7.0.6(transitive)
+ Addedis-stream@2.0.1(transitive)
+ Addedjson-bigint@1.0.0(transitive)
+ Addedjwa@2.0.0(transitive)
+ Addedjws@4.0.0(transitive)
+ Addedms@2.1.3(transitive)
+ Addedsafe-buffer@5.2.1(transitive)
+ Addeduuid@9.0.1(transitive)