Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@l2ysho
Last active January 15, 2020 09:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save l2ysho/d1661cc42ca68ef8624f08e3beff0dae to your computer and use it in GitHub Desktop.
Save l2ysho/d1661cc42ca68ef8624f08e3beff0dae to your computer and use it in GitHub Desktop.
express utils and middlewares
/**
* Logging with morgan
* Custom log format
* Logging to file from config
*/
import Morgan from 'morgan'
import config from 'config'
import path from 'path'
import * as rotator from 'file-stream-rotator'
const { logs } = config.get('files')
export default Morgan((tokens, req, res) => [
req.tag,
tokens['remote-addr'](req, res),
tokens['remote-user'](req, res),
tokens.date(req, res, 'iso'),
tokens.method(req, res),
tokens.url(req, res),
tokens.status(req, res),
tokens.res(req, res, 'content-length'), '-',
tokens.referrer(req, res),
tokens['user-agent'](req, res),
tokens['response-time'](req, res), 'ms'
].join(' '), {
stream: rotator.getStream({
filename: path.join(logs, 'access', 'access-%DATE%.log'),
frequency: 'daily',
verbose: false,
date_format: 'YYYY-MM-DD'
})
})
/**
* * Request marker middleware
* Create pseudo-random tag for each incoming request
* used to indentificate a requests in debug and error logs.
*/
import Debug from 'debug'
import { Request, Response, NextFunction } from 'express'
const debug = Debug('middlewares:requestMarker')
export default (req: Request, res: Response, next: NextFunction) => {
const tag = `#${Math.random().toString(32).substring(2, 7).toUpperCase()}`
debug('Create request tag', tag)
req.tag = tag
return next()
}
/**
* Simple endpoint for app version info
*/
import express from 'express'
const router: express.Router = express.Router();
export default () => {
router.get('/', async (req: express.Request, res: express.Response, next: express.NextFunction) => {
try {
const result = {
name: process.env.npm_package_name,
version: process.env.npm_package_version,
env: process.env.NODE_ENV,
host: process.env.HOST,
memmoryUsage: {
rss: `${formatMemmoryUsage(memoryData.rss)} -> Resident Set Size - total memory allocated for the process execution`,
heapTotal: `${formatMemmoryUsage(memoryData.heapTotal)} -> total size of the allocated heap`,
heapUsed: `${formatMemmoryUsage(memoryData.heapUsed)} -> actual memory used during the execution`,
external: `${formatMemmoryUsage(memoryData.external)} -> V8 external memory`,
}
}
return res.json(result)
} catch (err) {
return next(err)
}
})
return router;
};
//* npm modules
import winston from 'winston'
import config from 'config'
import path from 'path'
import DailyRotateFile from 'winston-daily-rotate-file'
//* config
const { logs } = config.get('files')
const { format, createLogger } = winston;
const {
combine,
timestamp,
label,
printf
} = format
// Set a custom format for error logs
const myFormat = printf(info => `[${info.tag}] [${info.status}] [${info.timestamp}] ${info.message} ${info.stack || ''}`)
const onlyErrorFilter = () => format(info => info.level === 'error' && info)();
const exceptErrorFilter = () => format(info => info.level !== 'error' && info)();
export default (type: string) => {
const transports: any = [
new (DailyRotateFile)({
filename: path.join(logs, type, 'info-%DATE%.log'),
datePattern: 'YYYY-MM-DD',
zippedArchive: true,
maxSize: '20m',
maxFiles: '14d',
frequency: '24h',
format: combine(
exceptErrorFilter(),
label({ label: type }),
timestamp(),
myFormat
)
}),
new (DailyRotateFile)({
filename: path.join(logs, type, 'error-%DATE%.log'),
datePattern: 'YYYY-MM-DD',
zippedArchive: true,
maxSize: '20m',
maxFiles: '14d',
frequency: '24h',
format: combine(
onlyErrorFilter(),
label({ label: type }),
timestamp(),
myFormat
)
})
];
if (process.env.NODE_ENV !== 'test') {
transports.push(new winston.transports.Console({
format: format.json()
}))
}
return createLogger({
transports
})
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment