feat(middleware-logger): write to stream
MODIFY
packages/@integration/src/app.ts
packages/@integration/src/app.ts
import { httpListener } from '@marblejs/core';
import { bodyParser$ } from '@marblejs/middleware-body';
-import { loggerWithOpts$ } from '@marblejs/middleware-logger';
+import { logger$ } from './middlewares/logger.middleware';
import { api$ } from './effects/api.effects';
const middlewares = [
- loggerWithOpts$({ silent: false }),
+ logger$,
bodyParser$,
];

ADD
packages/@integration/src/middlewares/logger.middleware.ts
+import { loggerWithOpts$ } from '@marblejs/middleware-logger';
+import { createWriteStream } from 'fs';
+import { join } from 'path';
+
+const writePath = join(__dirname, '../../', 'access.log');
+const stream = createWriteStream(writePath, { flags: 'a' });
+const options = { silent: false, stream };
+
+export const logger$ = loggerWithOpts$(options);

DELETE
packages/middleware-logger/src/console.factory.ts
-import chalk from 'chalk';
-
-export const formatStatusCode = (statusCode: number): string =>
- statusCode >= 400
- ? chalk.yellow(statusCode.toString())
- : chalk.green(statusCode.toString());
-
-export const printLog = (
- method: string,
- url: string,
- statusCode: string,
- formattedTime: string
-) => {
- console.info(`%s %s %s %s`, method, url, statusCode, formattedTime);
-};

ADD
packages/middleware-logger/src/logger.factory.ts
+import { HttpRequest, HttpResponse } from '@marblejs/core';
+import { Timestamp } from 'rxjs';
+import chalk from 'chalk';
+import { factorizeTime } from './time.factory';
+
+type LogFactorizerOptions = {
+ colorize?: boolean;
+ timestamp?: boolean;
+};
+
+const colorizeStatusCode = (statusCode: number): string =>
+ statusCode >= 400
+ ? chalk.yellow(statusCode.toString())
+ : chalk.green(statusCode.toString());
+
+export const factorizeLog =
+ (res: HttpResponse, stamp: Timestamp<HttpRequest>) =>
+ (opts: LogFactorizerOptions = {}) => {
+ const { method, url } = stamp.value;
+
+ const timestamp = opts.timestamp
+ ? new Date().toISOString()
+ : '';
+
+ const statusCode = opts.colorize
+ ? colorizeStatusCode(res.statusCode)
+ : String(res.statusCode);
+
+ const time = factorizeTime(stamp.timestamp);
+
+ return prepareLogString({ timestamp, method, url, statusCode, time });
+ };
+
+export const prepareLogString = (opts: {
+ timestamp?: string;
+ method: string;
+ url: string;
+ statusCode: string;
+ time: string;
+}) =>
+ !!opts.timestamp
+ ? `${opts.timestamp} ${opts.method} ${opts.url} ${opts.statusCode} ${opts.time}`
+ : `${opts.method} ${opts.url} ${opts.statusCode} ${opts.time}`;

MODIFY
packages/middleware-logger/src/logger.middleware.ts
packages/middleware-logger/src/logger.middleware.ts
import { Middleware, HttpRequest, HttpResponse } from '@marblejs/core';
-import { compose, Maybe } from '@marblejs/core/dist/+internal';
+import { Maybe } from '@marblejs/core/dist/+internal';
import { WriteStream } from 'fs';
import { fromEvent, Timestamp } from 'rxjs';
import { timestamp, tap, map, take, filter, mapTo } from 'rxjs/operators';
-import { printLog, formatStatusCode } from './console.factory';
-import { formatTime, getTimeDifferenceMs } from './time.factory';
+import { factorizeLog } from './logger.factory';
export interface LoggerOptions {
silent?: boolean;
@@ -20,6 +19,10 @@ const isRequest = (opts: LoggerOptions) => ({ value: req }: Timestamp<HttpReques
.map(filter => filter(req))
.valueOr(true);
+const writeToStream = (stream: WriteStream, chunk: string) => {
+ stream.write(`${chunk}\n\n`);
+};
+
const handleFinishEvent = (res: HttpResponse, opts: LoggerOptions) => (stamp: Timestamp<HttpRequest>) =>
fromEvent(res, 'finish')
.pipe(
@@ -28,13 +31,14 @@ const handleFinishEvent = (res: HttpResponse, opts: LoggerOptions) => (stamp: Ti
filter(isNotSilent(opts)),
filter(isRequest(opts)),
)
- .subscribe(({ value: req, timestamp }) => {
- printLog(
- req.method,
- req.url,
- formatStatusCode(res.statusCode),
- compose(formatTime, getTimeDifferenceMs)(new Date(timestamp))
- );
+ .subscribe(stamp => {
+ const log = factorizeLog(res, stamp);
+ const fileLog = log({ colorize: false, timestamp: true });
+ const consoleLog = log({ colorize: true });
+
+ if (opts.stream) { writeToStream(opts.stream, fileLog); }
+
+ console.info(consoleLog);
});
/**

MODIFY
packages/middleware-logger/src/time.factory.ts
packages/middleware-logger/src/time.factory.ts
+import { compose } from '@marblejs/core/dist/+internal';
+
export const formatTime = (timeMs: number) =>
timeMs > 1000
? `${timeMs / 1000}s`
@@ -5,3 +7,9 @@ export const formatTime = (timeMs: number) =>
export const getTimeDifferenceMs = (startTime: Date): number =>
new Date().getTime() - startTime.getTime();
+
+export const factorizeTime = (timestamp: number) =>
+ compose(
+ formatTime,
+ getTimeDifferenceMs
+ )(new Date(timestamp));

feat(middleware-logger): write to stream