Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@aircall/logger

Package Overview
Dependencies
Maintainers
5
Versions
58
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@aircall/logger - npm Package Compare versions

Comparing version 2.8.5 to 3.0.3

src/constants/log_schema.ts

59

CHANGELOG.md

@@ -1,6 +0,59 @@

# Change Log
# @aircall/logger
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## 3.0.3
### Patch Changes
- 63c3059: allow logger lib to be published to npm
## 3.0.2
### Patch Changes
- 3ae0677: Support QA env on bus
## 3.0.1
### Patch Changes
- ac67b6c: Stablize packages release
## 3.0.0
### Major Changes
- 2466248: migrate the logger module
## 0.3.2
### Patch Changes
- a7a8df5: migrate to typescript v5
## 0.3.1
### Patch Changes
- 702089c: Bump typescript to v4.9
## 0.3.0
### Minor Changes
- 7b0ab10: Fix minor bugs and prettify existing files
## 0.2.0
### Minor Changes
- 1c2d0fe: move to pnpm and adjust the dependencies to add all the missin ones
## 0.1.0
### Minor Changes
- c74b4e9: migrate the logger into hydra and rework the log-domains pkg
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.8.5](https://gitlab.com/aircall/shared/front-end-modules/compare/@aircall/logger@2.8.4...@aircall/logger@2.8.5) (2023-02-08)

@@ -7,0 +60,0 @@

60

package.json
{
"name": "@aircall/logger",
"version": "2.8.5",
"main": "dist/index.js",
"module": "dist/logger.esm.js",
"types": "dist/index.d.ts",
"version": "3.0.3",
"description": "Aircall Next Logger Module",
"main": "src/index.ts",
"types": "src/index.ts",
"sideEffects": false,
"scripts": {
"compile:schema:validation": "rm -rf src/validate-schema.js && ts-node scripts/validations/build-validate-schema.mjs",
"prestart": "yarn compile:schema:validation",
"prebuild": "yarn compile:schema:validation",
"start": "npx tsdx watch",
"clean": "rm -rf dist",
"build": "npx tsdx build"
},
"publishConfig": {
"access": "public"
},
"gitHead": "660ddb4e03853b2a948d08409fe9a1afb64f7472",
"husky": {
"hooks": {
"pre-commit": "tsdx lint"
}
},
"size-limit": [
{
"path": "dist/logger.cjs.production.min.js",
"limit": "24 KB"
},
{
"path": "dist/logger.esm.js",
"limit": "15 KB"
}
],
"devDependencies": {
"@aircall/eslint-config": "1.2.3",
"@aircall/tsconfig": "1.2.1",
"@size-limit/preset-small-lib": "8.1.0",
"@types/jest": "29",
"eslint": "8.30.0",
"husky": "8.0.1",
"size-limit": "8.1.0",
"tsdx": "0.14.1",
"tslib": "2.4.0"
},
"dependencies": {
"@datadog/browser-logs": "4.23.3",
"ajv": "8.11.0",
"ajv-formats": "2.1.1",
"redux": "4.2.0"
"@datadog/browser-logs": "4.17.1",
"@datadog/browser-core": "4.24.0"
},
"devDependencies": {
"ts-node": "^10.9.1"
"scripts": {
"dev": "tsdx watch",
"build": "tsdx build",
"test": "tsdx test --passWithNoTests",
"posttest": "pnpm run size",
"lint": "eslint --ext ts src",
"size": "size-limit"
}
}
}

@@ -18,3 +18,1 @@ global.console = {

};
jest.mock('./src/validate-schema', () => jest.fn(), { virtual: true });

@@ -16,1 +16,14 @@ // Number of stored actions for the debug mode;

export const DEFAULT_SENSITIVE_TEXT = '<sensitive>';
// Our common log schema relies on those custom keywords
// @see https://ajv.js.org/strict-mode.html#json-schema-schemas
export const CUSTOM_LOG_SCHEMA_KEYWORDS = [
'destination',
'bytes_read',
'bytes_written',
'connectivity',
'downlink_kbps',
'signal_strength',
'uplink_kbps',
'useragent_details'
];

@@ -1,3 +0,1 @@

export * from './actions';
export * from './middleware';
export * from './Logger';

@@ -1,32 +0,28 @@

jest.mock('@datadog/browser-logs');
import { datadogLogs, StatusType } from '@datadog/browser-logs';
import { Logger, LOGGER_ENVIRONMENT, LOGGER_LEVEL } from './Logger';
import { datadogLogs, StatusType } from '@datadog/browser-logs';
jest.mock('@datadog/browser-logs');
const properties = { foo: 'BAR' };
const [message, token] = ['MESSAGE', 'TOKEN'];
const version = 'RELEASE';
const environment = LOGGER_ENVIRONMENT.TEST;
const service = 'phone';
const user = {
id: 0,
company_id: 1
};
describe('Logger', (): void => {
beforeEach((): void => {
jest.spyOn(console, 'debug').mockImplementation((): void => undefined);
jest.spyOn(console, 'info').mockImplementation((): void => undefined);
jest.spyOn(console, 'warn').mockImplementation((): void => undefined);
jest.spyOn(console, 'error').mockImplementation((): void => undefined);
});
const user_session = {
company_id: 0,
device: 'DEVICE',
environment,
release: version,
user_id: user.id,
is_trial: true,
tier_level: 'a',
provider: 'Twilio'
};
afterEach((): void => {
jest.restoreAllMocks();
});
const logger = new Logger();
it('should be an instance of Logger', (): void => {
const logger = new Logger({
token,
level: LOGGER_LEVEL.debug
});
describe('Logger', (): void => {
it('should be an instance of Logger', (): void => {
expect(logger).toBeInstanceOf(Logger);

@@ -37,2 +33,6 @@ });

it('should queue events before initialization', (): void => {
const logger = new Logger({
token,
level: LOGGER_LEVEL.debug
});
logger.info('FOO');

@@ -46,22 +46,12 @@ expect(logger.queue.length).toEqual(1);

it('should set properties', (): void => {
jest.spyOn(logger, 'setContext');
const context = {
service,
user_session
};
logger.init({
context,
const logger = new Logger({
token,
level: LOGGER_LEVEL.debug,
version,
environment,
service,
user
level: LOGGER_LEVEL.debug
});
logger.init();
expect(logger.level).toEqual(LOGGER_LEVEL.debug);
expect(logger.initialized).toEqual(true);
expect(datadogLogs.init).toHaveBeenCalled();
expect(logger.setContext).toHaveBeenCalledWith(context);
expect(datadogLogs.logger.setContext).toHaveBeenCalledWith(context);
});

@@ -71,6 +61,16 @@ });

describe('log', (): void => {
let logger: Logger;
beforeEach((): void => {
logger = new Logger({
token,
level: LOGGER_LEVEL.debug
});
logger.init();
});
it('should call logger.log', (): void => {
jest.spyOn(datadogLogs.logger, 'log');
const logSpy = jest.spyOn(datadogLogs.logger, 'log');
logger.log(StatusType.info, message, properties);
expect(datadogLogs.logger.log).toHaveBeenCalledWith(message, properties, StatusType.info);
expect(logSpy).toHaveBeenCalledWith(message, properties, StatusType.info);
});

@@ -86,2 +86,11 @@

describe('debug', (): void => {
let logger: Logger;
beforeEach((): void => {
logger = new Logger({
token,
level: LOGGER_LEVEL.debug
});
logger.init();
});
it('should call logger.debug', (): void => {

@@ -101,2 +110,11 @@ jest.spyOn(datadogLogs.logger, 'debug');

describe('info', (): void => {
let logger: Logger;
beforeEach((): void => {
logger = new Logger({
token,
level: LOGGER_LEVEL.debug
});
logger.init();
});
it('should call logger.info', (): void => {

@@ -116,2 +134,11 @@ jest.spyOn(datadogLogs.logger, 'info');

describe('warn', (): void => {
let logger: Logger;
beforeEach((): void => {
logger = new Logger({
token,
level: LOGGER_LEVEL.debug
});
logger.init();
});
it('should call logger.warn', (): void => {

@@ -131,2 +158,11 @@ jest.spyOn(datadogLogs.logger, 'warn');

describe('error', (): void => {
let logger: Logger;
beforeEach((): void => {
logger = new Logger({
token,
level: LOGGER_LEVEL.debug
});
logger.init();
});
it('should call logger.error', (): void => {

@@ -146,2 +182,11 @@ jest.spyOn(datadogLogs.logger, 'error');

describe('cleanProperties', (): void => {
let logger: Logger;
beforeEach((): void => {
logger = new Logger({
token,
level: LOGGER_LEVEL.debug
});
logger.init();
});
it('return empty object if the properties are not defined', (): void => {

@@ -207,35 +252,2 @@ expect(logger.cleanProperties()).toEqual({});

});
describe('beforeSendListener', (): void => {
//@ts-ignore
Date.now = jest.fn(() => new Date(2022, 7, 24, 8, 32, 16));
const logPayload = {
date: 1660119130,
foo: 'BAR',
bar: 10,
message: 'message',
status: StatusType.info,
view: { url: 'https://phone.aircall-staging.com/' }
};
it('should add mandatory fields and validate schema', (): void => {
logger.compiledLogSchema = jest.fn().mockReturnValue('test');
jest.spyOn(console, 'log');
const expected = {
level: LOGGER_LEVEL.info,
version,
env: environment,
host: '',
service,
timestamp: '2022-08-24T08:32:16.000Z',
user,
...logPayload
};
logger.beforeSendListener(logPayload, version, environment, service, user);
expect(logger.compiledLogSchema).toHaveBeenCalledWith(expected);
expect(console.log).toBeCalledTimes(0);
});
});
});

@@ -1,10 +0,12 @@

import { datadogLogs as sdk, StatusType, HandlerType, LogsEvent } from '@datadog/browser-logs';
import { Context, ConsoleApiName } from '@datadog/browser-core';
import { Context } from '@datadog/browser-core';
import {
HandlerType,
LogsInitConfiguration,
datadogLogs as sdk,
StatusType
} from '@datadog/browser-logs';
import { SENSITIVE_KEYS, DEFAULT_SENSITIVE_TEXT } from './constants';
import { containsAValue, isString, deepMap, isObject, isArray } from './utils';
import { DEFAULT_SENSITIVE_TEXT, SENSITIVE_KEYS } from './constants';
import { containsAValue, deepMap, isArray, isObject, isString } from './utils';
// @ts-ignore
import validate from './validate-schema';
export { StatusType as LOGGER_LEVEL };

@@ -21,64 +23,24 @@

export declare interface User extends Context {
id?: number;
company_id?: number;
// cti_name?: string;
// device: string;
// electron_version?: string;
// environment: LOGGER_ENVIRONMENT;
// release: string;
// is_trial?: boolean;
// tier_level?: string;
// provider?: string;
export interface LoggerOptions {
token: string;
level: StatusType;
debug?: boolean;
}
export declare interface UserSession extends Context {
company_id?: number;
cti_name?: string;
device: string;
electron_version?: string;
environment: LOGGER_ENVIRONMENT;
release: string;
user_id?: number;
is_trial?: boolean;
tier_level?: string;
provider?: string;
export interface LoggerInitOptions {
beforeSend: LogsInitConfiguration['beforeSend'];
}
export declare interface UserContext extends Context {
service: string;
user_session: UserSession;
}
export declare interface LoggerInitOptions {
context: UserContext;
token: string;
level: StatusType;
version: string;
environment: LOGGER_ENVIRONMENT;
service: string;
user: User;
forwardConsoleLogs?: ConsoleApiName[] | 'all';
}
export class Logger {
public level: StatusType;
public level: StatusType | undefined;
public initialized = false;
public queue: Function[] = [];
public queue: Array<() => void> = [];
public logSchemaValidator: any;
public compiledLogSchema: any;
constructor(readonly options: LoggerOptions) {}
// Init SDK with user informations, token and level
public init({
level,
context,
token,
version,
environment,
service,
user,
forwardConsoleLogs
}: LoggerInitOptions): void {
const isDevelopment: boolean =
context.user_session.environment === LOGGER_ENVIRONMENT.DEVELOPMENT;
this.compiledLogSchema = validate;
public init(initOptions?: LoggerInitOptions): void {
const { token, debug, level } = this.options;

@@ -89,9 +51,8 @@ sdk.init({

forwardErrorsToLogs: true,
forwardConsoleLogs: forwardConsoleLogs ?? ['error', 'warn'], // TODO PH-7453: do we want to forward warn logs as well?
forwardConsoleLogs: ['error', 'warn'], // TODO PH-7453: do we want to forward warn logs as well?
sampleRate: 100,
beforeSend: log => this.beforeSendListener(log, version, environment, service, user)
beforeSend: initOptions?.beforeSend
});
this.setContext(context);
sdk.logger.setHandler(isDevelopment ? HandlerType.console : HandlerType.http);
sdk.logger.setHandler(debug ? HandlerType.console : HandlerType.http);

@@ -103,70 +64,4 @@ this.setLevel(level);

/**
* Remove sensitive properties, add mandatory fields and validate the payload against the log schema.
*
* @param log
* @param version
* @param environment
* @param service
* @param user
*/
public beforeSendListener(
log: LogsEvent,
version: string,
environment: string,
service: string,
user: User
): void {
// TODO PH-7453: move the clean properties function here
this.addMandatoryFields(log, version, environment, service, user);
const valid = this.compiledLogSchema(log);
if (!valid) {
console.log(
'An error occured while validating the log payload. For more information, please refer to distributed logging and tracing best practices documentation.',
{
error: this.compiledLogSchema.errors,
log
}
);
}
}
/**
* Every logs must include mandatory fields such as the environment or the version for instance.
* This function adds all of them into the log payload.
*
* @param log
* @param version
* @param environment
* @param service
* @param user
* @returns
*/
private addMandatoryFields(
log: LogsEvent,
version: string,
environment: string,
service: string,
user: User
) {
const currentDate = new Date(Date.now());
const datadogInternalContext = sdk.getInternalContext();
log.version = version;
log.env = environment;
log.service = service;
log.host = datadogInternalContext?.session_id || '';
log.timestamp = currentDate.toISOString();
log.level = log.status;
log.user = user;
}
// set logger context
public setContext(context: UserContext) {
sdk.logger.setContext(context);
}
// Send logs or enqueue them if the SDK isn't initialized
private logOrEnqueue(fn: Function): void {
private logOrEnqueue(fn: () => void): void {
this.initialized ? fn() : this.queue.push(fn);

@@ -173,0 +68,0 @@ }

@@ -1,2 +0,2 @@

import { mapObject, map, deepMap, containsAValue } from './utils';
import { containsAValue, deepMap, map, mapObject } from './utils';

@@ -3,0 +3,0 @@ describe('utils', () => {

{
"extends": "../../tsconfig.json",
"extends": "@aircall/tsconfig/base.json",
"compilerOptions": {
"allowJs": true,
"baseUrl": ".",
"rootDir": "./src",
"outDir": "./dist",
"paths": {
"@aircall/*": ["../../node_modules/@aircall/*/src"]
}
"target": "es2020",
"rootDir": "./src"
},
"include": ["**/*.ts"],
"exclude": ["node_modules", "dist", "scripts", "**/*.spec.ts"]
}
"include": [
"**/*.ts"
],
"exclude": [
"dist",
"node_modules"
]
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc