Skip to content

Instantly share code, notes, and snippets.

@jimmiehansson
Created February 4, 2018 15:10
Show Gist options
  • Save jimmiehansson/e3115851264252d026db102078ac36ff to your computer and use it in GitHub Desktop.
Save jimmiehansson/e3115851264252d026db102078ac36ff to your computer and use it in GitHub Desktop.
LogParser
'use strict';
/**
* This notation was generated by templates.
* // -------------------------------------------------
* GLOBAL FILE NOTATIONS
* Project of: Rocketdesk Auth
* Filename: LogParser.js by jimmie
* Created: 2017-07-27 @ 16:00
* Product of: Rocketdesk.net
* // -------------------------------------------------
* Make sure to read the code style documentation
* at http://docs.rocketdesk.net
* // -------------------------------------------------
* Repository link: https://github.com/jimmiehansson/rocket.git
* // -------------------------------------------------
*/
/**
* Require node specific modules and libraries
* here to separate from the rest of the code.
*/
const path = require('path');
const fs = require('fs');
const moment = require('moment');
const series = require('async/series');
/**
* Import universal/associated libraries
* here to separate from the rest of the code.
*/
import {
PRE_ENV
} from './Constants/Environment';
import {
verbose,
infoHandler,
errorHandler,
makeVerbose,
startTimer,
endTimer
} from './Utils';
import {
FS_LOG_PARSER_BASE_DIR,
FS_LOG_PARSER_BASE_DIR_MASK,
FS_LOG_PARSER_FILE_UNICODE,
FS_LOG_PARSER_FILE_OPEN_MODE,
FS_LOG_PARSER_FILE_WRITE_UNICODE,
FS_LOG_PARSER_FILE_WRITE_MASK,
FS_LOG_PARSER_FILE_WRITE_FLAG,
FS_LOG_PARSER_FILE_BASE_NAME,
FS_LOG_PARSER_FILE_INIT_BUFFER,
FS_LOG_PARSER_FILE_JSON_DELIM,
FS_LOG_PARSER_BUFFER_ENCODING,
FS_LOG_PARSER_FILE_TEMPORARY_BASE_NAME,
FS_LOG_PARSER_FILE_TEMPORARY_INIT_BUFFER
} from './Constants/Common';
import {
FS_LOG_PARSER_CREATE_DIRECTORY,
FS_LOG_PARSER_DIRECTORY_CREATED,
FS_LOG_PARSER_DIRECTORY_NOT_CREATED,
FS_LOG_PARSER_DIRECTORY_NOT_EXIST,
FS_LOG_PARSER_DIRECTORY_EXIST,
FS_LOG_PARSER_FILE_NOT_EXIST,
FS_LOG_PARSER_FILE_EXIST,
FS_LOG_PARSER_FILE_NOT_CREATED,
FS_LOG_PARSER_FILE_CREATED,
FS_LOG_PARSER_CREATE_FILE,
FS_LOG_PARSER_FILE_SYSTEM_NOT_READY,
FS_LOG_PARSER_FILE_SYSTEM_READY,
FS_LOG_PARSER_FILE_SYSTEM_TIME_ALIAS
} from './Constants/Language/English';
/**
* CLARIFY: Should return whether the ENOENT
* value returned as -2 (Directory does not exist)
* @param match
*/
const ENOENT2 = match => PRE_ENV==='local' && match.errno===-2;
/**
* DOING: Should resolve the root
* path to the folder containing the logs.
* @param dir
*/
const resolveBaseDirectory = dir => path.resolve(FS_LOG_PARSER_DIR,dir);
/**
* DOING: Should resolve the path
* to the folders containing the logs.
* @param dir
*/
const resolveParentDirectory = dir => path.resolve(FS_LOG_PARSER_BASE_DIR, dir);
/**
* DOING: Should resolve the child directory
* of the current date.
* @param dir
*/
const resolveChildDirectory = dir => path.resolve(FS_LOG_PARSER_BASE_DIR, `${dir}/${moment().format('YYYY-MM-DD')}`);
/**
* DOING: Should return the name
* of the parent directory.
* @param dir
*/
const getParentDireectory = dir => dir;
/**
* DOING: Should return the name
* of the child directory.
* @param dir
*/
const getChildDirectory = dir => `${dir}/${moment().format('YYYY-MM-DD')}`;
/**
* DOING: Should generate an absolute
* path and return it to the current
* file.
* @param dir
* @param file
*/
const generateFilePath = (dir, file) => `${resolveChildDirectory(dir)}/${file}`;
/**
* DOING: Should generate an absolute
* path for the dump file and return
* it.
* @param dir
*/
const generateTemporaryFilePath = dir => `${resolveChildDirectory(dir)}/`;
/**
* DOING: Should generate an absolute
* path for the temporary file and
* return it.
* @param file
*/
const generateTemporaryFileName = file => `${FS_LOG_PARSER_FILE_TEMPORARY_BASE_NAME}`;
/**
* DOING: Should return if the buffer
* is of zero length.
* @param buffer
*/
const bufferIsEmpty = buffer => PRE_ENV==='local' && buffer.length===0;
/**
* CLARIFY: Should return an error dispatch
* for each consecutive descriptor.
* @param err
* @param handler
* @param reject
*/
const errorDispatch = (err, handler, reject) => {
if(verbose(err)){
errorHandler(handler, err);
}
return reject(false)
};
/**
* DOING: Should create the proper
* directory for the current stream.
* @param dir
* @param mode
* @return {*}
*/
const createDirectory = (dir, mode) => {
return new Promise( (resolve, reject) => {
fs.mkdir(
(mode)
? resolveParentDirectory(dir)
: resolveChildDirectory(dir),
FS_LOG_PARSER_BASE_DIR_MASK, err => {
(err)
? errorDispatch(err, FS_LOG_PARSER_DIRECTORY_NOT_CREATED, reject)
: infoHandler(
makeVerbose(
FS_LOG_PARSER_DIRECTORY_CREATED,
(mode)
? resolveParentDirectory(dir)
: resolveChildDirectory(dir)
), (mode)
? resolveParentDirectory(dir)
: resolveChildDirectory(dir));
});
return resolve(true);
});
};
/**
* DOING: Should return a promise
* for the file descriptor to see if the
* directory has the right permissions and exists.
* @param dir
* @param mode (true parent dir, false child dir)
* @return {Promise}
*/
const directoryExists = (dir, mode) => {
return new Promise ( (resolve, reject) => {
fs.access(
(mode)
? resolveParentDirectory(dir)
: resolveChildDirectory(dir),
fs.constants.R_OK | fs.constants.R_W, err => {
if(verbose(err) && ENOENT2(err)) {
errorHandler(
makeVerbose(FS_LOG_PARSER_DIRECTORY_NOT_EXIST, (mode)
? resolveParentDirectory(dir)
: resolveChildDirectory(dir)),
err
);
createDirectory(dir, mode).then((e) => {
(e)
? infoHandler(makeVerbose(FS_LOG_PARSER_CREATE_DIRECTORY,
(mode)
? resolveParentDirectory(dir)
: resolveChildDirectory(dir)
))
: reject(e, FS_LOG_PARSER_DIRECTORY_NOT_CREATED, reject);
})
}
else{
infoHandler(makeVerbose(FS_LOG_PARSER_DIRECTORY_EXIST,
(mode)
? resolveParentDirectory(dir)
: resolveChildDirectory(dir)
));
}
return resolve(true);
});
});
};
/**
* DOING: Should return a promise
* for the file descriptor of the file
* being written to and its buffer file.
* @param mode
* @param path
* @param options
* @return {Promise}
*/
const fileExists = (
mode,
path,
options = {
encoding : FS_LOG_PARSER_FILE_UNICODE,
flag : FS_LOG_PARSER_FILE_OPEN_MODE
}) => {
return new Promise ( (resolve, reject) => {
fs.readFile(path, options, (err, data) => {
(err)
? errorDispatch(err, makeVerbose(FS_LOG_PARSER_FILE_NOT_EXIST, path), reject)
: infoHandler(makeVerbose(FS_LOG_PARSER_FILE_EXIST, path)) && data || bufferIsEmpty(data);
if(verbose(err) && ENOENT2(err)){
createFile(!!(mode), path, FS_LOG_PARSER_FILE_INIT_BUFFER).then(e => {
(e)
? infoHandler(makeVerbose(FS_LOG_PARSER_CREATE_FILE, path))
: errorDispatch(err, makeVerbose(FS_LOG_PARSER_FILE_NOT_CREATED, path), reject);
});
}
});
return resolve(true);
});
};
/**
* DOING: Should generate the JSON file
* to write the queries to.
* @param mode (true for json false for buffer)
* @param file
* @param data
* @param options
* @return {*}
*/
const createFile = (
mode,
file,
data,
options = {
encoding : FS_LOG_PARSER_FILE_WRITE_UNICODE,
mode : FS_LOG_PARSER_FILE_WRITE_MASK,
flag : FS_LOG_PARSER_FILE_WRITE_FLAG,
}) => {
return new Promise ( (resolve, reject) => {
fs.writeFile(
file,
(mode) ? JSON.stringify(data, null, FS_LOG_PARSER_FILE_JSON_DELIM) : data,
options,
err => {
(err)
? errorDispatch(err, makeVerbose(FS_LOG_PARSER_FILE_NOT_CREATED, file), reject)
: infoHandler(makeVerbose(FS_LOG_PARSER_FILE_CREATED, file));
});
return resolve(true);
});
};
/**
* DOING: Should return if parent directory
* exists to write the buffer.
* @param dir
*/
const checkParentDirectory = dir => directoryExists(dir, true);
/**
* DOING: Should return if the child directory
* exists to write the buffer.
* @param dir
*/
const checkChildDirectory = dir => directoryExists(dir, false);
/**
* DOING: Should return if the file buffer
* exists and is written.
* @param dir
*/
const checkLogFile = dir => fileExists(true, generateFilePath(dir, FS_LOG_PARSER_FILE_BASE_NAME));
/**
* DOING: Should return if the dump buffer
* exists and is written.
* @param dir
*/
const checkDumpFile = dir => fileExists(false,
generateTemporaryFilePath(dir, FS_LOG_PARSER_FILE_TEMPORARY_BASE_NAME)+generateTemporaryFileName());
/**
* DOING: Should prepare the initial setup
* for files and directories to write the
* query buffer to.
* @param dir
*/
const initFileSystem = dir => {
return new Promise( (resolve, reject) => {
series({
parent : (
callback => { checkParentDirectory(dir).then(parent => callback(null, parent)); }),
child : (
callback => { checkChildDirectory(dir).then(child => callback(null, child) ); }),
file : (
callback => { checkLogFile(dir).then(file => callback(null, file)); }),
dump : (
callback => { checkDumpFile(dir).then(dump => callback(null, dump)); }
)
}, (err, results)=> {
(err)
? errorDispatch(err, makeVerbose(FS_LOG_PARSER_FILE_SYSTEM_NOT_READY, results), reject)
: !!(results) && infoHandler(makeVerbose(FS_LOG_PARSER_FILE_SYSTEM_READY, JSON.stringify(results)));
});
return resolve(true);
});
};
/**
* DOING: Should return any event
* change to the buffer.
* @param dir
* @param options
* @return {Promise}
*/
const createWatcher = (
dir,
options = {
encoding: FS_LOG_PARSER_BUFFER_ENCODING
}) => {
return new Promise( (resolve, reject) => {
fs.watch(dir, options, (event, file)=> {
});
return resolve(true);
});
};
/**
* DOING: Should trigger on change
* event in the current watcher.
* @param watcher
*/
const watcherOnChange = watcher => watcher.on('change', change => change);
/**
* DOING: Should trigger on error
* event in the current watcher.
* @param watcher
*/
const watcherOnError = watcher => watcher.on('error', error => error);
/**
* DOING: Should close the current
* watcher attached to the buffer.
* @param watcher
*/
const watcherClose = watcher => watcher.close();
/**
* DOING: Should create a readable stream
* to the specified buffer.
* @param buffer
* @return {Promise}
*/
const createReadStream = buffer => {
return new Promise((resolve, reject) => {
buffer.on('read', read => { console.log('buffer read'); });
buffer.on('end', read => { console.log('read end'); });
return resolve(true);
});
};
/**
* DOING: Should trigger on error
* event in the current stream.
* @param stream
*/
const streamOnError = stream => stream.on('error', error => error);
/**
* DOING: Should trigger on open
* event in the current stream.
* @param stream
*/
const streamOnOpen = stream => stream.on('open', open => open);
/**
* DOING: Should trigger on readable
* event in the current stream.
* @param stream
*/
const streamOnReadable = stream => stream.on('readable', readable => readable);
/**
* DOING: Should return boolean
* if current stream is paused or not.
* @param stream
*/
const streamIsPaused = stream => stream.isPaused();
/**
* DOING: Should pause the current
* stream buffer.
* @param stream
*/
const streamPause = stream => stream.pause();
/**
* DOING: Should resume the current
* stream buffer.
* @param stream
*/
const streamResume = stream => stream.resume();
/**
* DOING: Should set the encoding
* of the current stream.
* @param stream
*/
const setStreamEncoding = stream => stream.setStreamEncoding();
/**
* DOING: Should set the stream pipe
* for the writable buffer.
* @param stream
* @param writable
*/
const setStreamPipe = (stream, writable) => stream.pipe(writable);
/**
* DOING: Should set the unpipe the
* current writable stream.
* @param stream
* @param writable
*/
const setStreamUnpipe = (stream, writable) => stream.unpipe(writable);
/**
* DOING: Should trigger on data
* event in the current stream.
* @param stream
*/
const streamOnData = stream => stream.on('data', data => data);
/**
* DOING: Should trigger on close
* event in the current stream.
* @param stream
*/
const streamOnClose = stream => stream.on('close', close => close);
/**
* DOING: Should trigger on end
* event in the current stream.
* @param stream
*/
const streamOnEnd = stream => stream.on('end', end => end);
/**
* DOING: Should return the n of bytes
* read from the current stream buffer.
* @param stream
*/
const getStreamBytesRead = stream => stream.bytesRead;
/**
* DOING: Should return the current
* stream size buffer.
* @param stream
* @param size
*/
const getStreamReadSize = (stream, size) => stream.read(size).length;
/**
* DOING: Should get the path to current
* stream being read in buffer.
* @param stream
*/
const getReadStreamPath = stream => stream.path;
/**
* DOING: Should scan the resolved directory path
* and return proper writable permissions and ownership.
* @param dir
*/
export const indexQuery = (dir) => {
startTimer(FS_LOG_PARSER_FILE_SYSTEM_TIME_ALIAS);
initFileSystem(dir)
.then( ready =>
console.log('Is the file system ready? ', ready)
);
endTimer(FS_LOG_PARSER_FILE_SYSTEM_TIME_ALIAS);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment