Skip to content

Commit

Permalink
feat(logstash): Tcp udp transport (#74)
Browse files Browse the repository at this point in the history
* feat(logstash): added dynamic logstash transport

* test: added tests for dynamic logstash transport

* refactor: fix cr

Co-authored-by: Arik Furman <furmanmail@gmail.com>
  • Loading branch information
ronkatz96 and DoctorVoid authored Aug 18, 2020
1 parent 8b77fc4 commit 0d889e3
Show file tree
Hide file tree
Showing 8 changed files with 2,525 additions and 2,754 deletions.
5,099 changes: 2,399 additions & 2,700 deletions package-lock.json

Large diffs are not rendered by default.

40 changes: 21 additions & 19 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,37 +59,39 @@
},
"homepage": "https://github.com/Enigmatis/polaris-logs#readme",
"dependencies": {
"@enigmatis/polaris-common": "^1.4.3",
"@enigmatis/polaris-common": "^1.4.5",
"clean-deep": "^3.3.0",
"object-sizeof": "^1.6.1",
"serialize-error": "^7.0.1",
"uuid": "^8.1.0",
"winston": "^3.2.1",
"winston-daily-rotate-file": "^4.4.2",
"winston-transport": "^4.3.0",
"uuid": "^8.3.0",
"winston": "^3.3.3",
"winston-daily-rotate-file": "^4.5.0",
"winston-logstash-ts": "^0.2.3",
"winston-transport": "^4.4.0",
"winston3-logstash-transport": "^1.0.1-c"
},
"devDependencies": {
"@commitlint/cli": "^8.3.5",
"@commitlint/config-conventional": "^8.3.4",
"@commitlint/cli": "^9.1.2",
"@commitlint/config-conventional": "^9.1.2",
"@semantic-release/changelog": "^5.0.1",
"@semantic-release/git": "^9.0.0",
"@types/jest": "^26.0.0",
"@types/node": "^14.0.13",
"@types/jest": "^26.0.10",
"@types/node": "^14.0.27",
"@types/serialize-error": "^4.0.1",
"@types/uuid": "^8.0.0",
"@types/uuid": "^8.3.0",
"@types/winston": "^2.4.4",
"@typescript-eslint/eslint-plugin": "^3.2.0",
"@typescript-eslint/parser": "^3.2.0",
"@typescript-eslint/eslint-plugin": "^3.9.0",
"@typescript-eslint/parser": "^3.9.0",
"eslint": "^7.7.0",
"eslint-config-prettier": "^6.11.0",
"eslint-plugin-prettier": "^3.1.4",
"husky": "^4.2.5",
"jest": "^26.0.1",
"jest": "^26.4.0",
"prettier": "^2.0.5",
"rimraf": "^3.0.2",
"semantic-release": "^17.0.8",
"ts-jest": "^26.1.0",
"eslint": "^7.2.0",
"eslint-config-prettier": "^6.11.0",
"eslint-plugin-prettier": "^3.1.3",
"typescript": "^3.9.5"
"semantic-release": "^17.1.1",
"ts-jest": "^26.2.0",
"typescript": "^3.9.7"
},
"husky": {
"hooks": {
Expand Down
1 change: 1 addition & 0 deletions src/configurations/logstash-protocol.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export enum LogstashProtocol {
TCP = 'tcp',
UDP = 'udp',
DYNAMIC = 'dynamic',
}
22 changes: 22 additions & 0 deletions src/transports/dynamic-logstash-transport.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { LogstashProtocol } from '../configurations/logstash-protocol';
import { LogstashOption, LogstashTransport } from 'winston-logstash-ts';

const sizeof = require('object-sizeof');

const MAX_UDP_PACKET_SIZE_IN_BYTES = 65535;
type DynamicProtocolOptions = Omit<LogstashOption, 'protocol'>;

export class DynamicLogstashTransport extends LogstashTransport {
constructor(options: DynamicProtocolOptions) {
super(options);
}
public send(message: any, callback: any): Promise<void> {
if (sizeof(message) < MAX_UDP_PACKET_SIZE_IN_BYTES) {
this.protocol = LogstashProtocol.UDP;
return super.send(message, callback);
} else {
this.protocol = LogstashProtocol.TCP;
return super.send(message, callback);
}
}
}
26 changes: 18 additions & 8 deletions src/winston-logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import * as winston from 'winston';
import * as DailyRotateFile from 'winston-daily-rotate-file';
import { LoggerConfiguration } from './configurations/logger-configuration';
import { Logger } from './logger-with-custom-levels';

const LogstashTransport = require('winston3-logstash-transport');
import { DynamicLogstashTransport } from './transports/dynamic-logstash-transport';
import { LogstashTransport } from 'winston-logstash-ts';
import { LogstashProtocol } from './configurations/logstash-protocol';

const timestampFormat = 'DD-MM-YYYY HH:mm:ss';

Expand Down Expand Up @@ -65,13 +66,22 @@ export const createLogger = (loggerConfiguration: LoggerConfiguration): Logger =
logger.on('error', (error) => console.error('logger error!', error));

if (loggerConfiguration.logstashConfigurations) {
let logstashTransport: LogstashTransport | DynamicLogstashTransport;
loggerConfiguration.logstashConfigurations.forEach((logstashConfiguration) => {
const logstashTransport = new LogstashTransport({
host: logstashConfiguration.host,
port: logstashConfiguration.port,
mode: logstashConfiguration.protocol,
format: logstashFormat,
});
if (logstashConfiguration.protocol === LogstashProtocol.DYNAMIC) {
logstashTransport = new DynamicLogstashTransport({
host: logstashConfiguration.host,
port: logstashConfiguration.port,
format: logstashFormat,
});
} else {
logstashTransport = new LogstashTransport({
host: logstashConfiguration.host,
port: logstashConfiguration.port,
protocol: logstashConfiguration.protocol,
format: logstashFormat,
});
}
logger.add(logstashTransport);
});
}
Expand Down
23 changes: 23 additions & 0 deletions test/dynamic-logstash-transport.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { LogstashProtocol } from '../src/configurations/logstash-protocol';
import { DynamicLogstashTransport } from '../src/transports/dynamic-logstash-transport';

jest.mock('object-sizeof', () => jest.fn().mockReturnValueOnce(50).mockReturnValueOnce(70000));

describe('dynamic-logstash-transport tests', () => {
const logstashHost = 'test';
const logstashPort = 8080;
const dynamicLogstashTransport = new DynamicLogstashTransport({
host: logstashHost,
port: logstashPort,
});
const message = 'hi';
const cb = {};
test('gets message and sends it using UDP', async () => {
await expect(dynamicLogstashTransport.send(message, cb)).rejects.toThrowError();
expect((dynamicLogstashTransport as any).protocol).toEqual(LogstashProtocol.UDP);
});
test('gets message and sends it using TCP', async () => {
await expect(dynamicLogstashTransport.send(message, cb)).rejects.toThrowError();
expect((dynamicLogstashTransport as any).protocol).toEqual(LogstashProtocol.TCP);
});
});
65 changes: 39 additions & 26 deletions test/winston-logger.test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
const LogstashTransport = require('winston3-logstash-transport');
import * as winston from 'winston';
import * as DailyRotateFile from 'winston-daily-rotate-file';
import { LoggerConfiguration } from '../src/configurations/logger-configuration';
import { LoggerLevel } from '../src/configurations/logger-level';
import { LogstashProtocol } from '../src/configurations/logstash-protocol';
import * as winstonLogger from '../src/winston-logger';
import { LogstashTransport } from 'winston-logstash-ts';

jest.mock('winston', () => {
return {
Expand Down Expand Up @@ -35,6 +35,8 @@ jest.mock('winston-daily-rotate-file', () => {
});
jest.mock('winston3-logstash-transport', () => jest.fn());

jest.mock('winston-logstash-ts');

describe('winston-logger tests', () => {
const loggerLevel = LoggerLevel.INFO;
const logstashHost = 'test';
Expand Down Expand Up @@ -83,14 +85,11 @@ describe('winston-logger tests', () => {

winstonLogger.createLogger(config);

expect(LogstashTransport).toHaveBeenCalledTimes(1);
expect(LogstashTransport).toHaveBeenCalledWith(
expect.objectContaining({
host: logstashHost,
port: logstashPort,
mode: logstashProtocol,
}),
);
expect(LogstashTransport).toHaveBeenCalledWith({
host: logstashHost,
port: logstashPort,
protocol: logstashProtocol,
});
});

test('creating logger with configuration of multiple logstash services', () => {
Expand All @@ -116,23 +115,37 @@ describe('winston-logger tests', () => {

winstonLogger.createLogger(config);

expect(LogstashTransport).toHaveBeenCalledTimes(2);
expect(LogstashTransport).toHaveBeenNthCalledWith(
1,
expect.objectContaining({
host: logstashHost,
port: logstashPort,
mode: logstashProtocol,
}),
);
expect(LogstashTransport).toHaveBeenNthCalledWith(
2,
expect.objectContaining({
host: anotherLogstashHost,
port: anotherLogstashPort,
mode: anotherLogstashProtocol,
}),
);
expect(LogstashTransport).toHaveBeenCalledWith({
host: logstashHost,
port: logstashPort,
protocol: logstashProtocol,
});
expect(LogstashTransport).toHaveBeenCalledWith({
host: anotherLogstashHost,
port: anotherLogstashPort,
protocol: anotherLogstashProtocol,
});
});

test('creating logger with configuration of dynamic logstash service', () => {
const anotherLogstashProtocol: LogstashProtocol = LogstashProtocol.DYNAMIC;
const config: LoggerConfiguration = {
loggerLevel,
logstashConfigurations: [
{
host: logstashHost,
port: logstashPort,
protocol: anotherLogstashProtocol,
},
],
};

winstonLogger.createLogger(config);

expect(LogstashTransport).toHaveBeenCalledWith({
host: logstashHost,
port: logstashPort,
});
});

test('creating logger with configuration for console writing', () => {
Expand Down
3 changes: 2 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
"moduleResolution": "node",
"types": ["jest", "node"],
"declaration": true,
"lib": ["es6", "es2017", "esnext"]
"lib": ["es6", "es2017", "esnext"],
"skipLibCheck": true
},
"exclude": ["node_modules"]
}

0 comments on commit 0d889e3

Please sign in to comment.