nope/lib/logger/fileLogging.ts

173 lines
4.3 KiB
TypeScript
Raw Normal View History

2021-05-21 17:21:53 +00:00
/**
* @author Martin Karkowski
* @email m.karkowski@zema.de
* @create date 2021-05-21 16:44:59
2021-10-19 19:27:30 +00:00
* @modify date 2021-10-19 17:47:56
2021-05-21 17:21:53 +00:00
* @desc [description]
*/
import { writeFile } from "fs";
import { join } from "path";
import { createFile } from "../helpers/fileMethods";
import { replaceAll } from "../helpers/stringMethods";
2022-03-18 08:06:45 +00:00
import { sleep } from "../index.browser";
2021-05-21 17:21:53 +00:00
import { getCentralNopeLogger, getNopeLogger } from "./getLogger";
import { formatMsgForConsole } from "./nopeLogger";
2021-05-21 17:21:53 +00:00
export const CURRENT_DATE = _parsableISOString();
export const DEFAULT_LOG_LOCATION = join(process.cwd(), "logs");
const DEFAULT_FILE = join(DEFAULT_LOG_LOCATION, CURRENT_DATE + ".log");
function _parsableISOString(date = new Date()) {
let isoString = date.toISOString();
isoString = replaceAll(isoString, ":", "-");
isoString = replaceAll(isoString, ".", "-");
return isoString;
}
/**
* Generates a Log-File Path based on the given name with the following format:
* /logs/{name}_{date}.log
*
* @export
* @param {string} name Name of the File.
2022-01-18 07:01:50 +00:00
* @return {string}
* @backend **Only in Nodejs available**
2021-05-21 17:21:53 +00:00
*/
export function generateLogfilePath(name: string): string {
return join(DEFAULT_LOG_LOCATION, name + "_" + _parsableISOString() + ".log");
}
/**
* Function to use a log file instead of the console log.
*
2022-01-18 07:01:50 +00:00
* @author M.Karkowski
2021-05-21 17:21:53 +00:00
* @export
2022-01-18 07:01:50 +00:00
* @param {string} [pathToFile=DEFAULT_FILE] Path to the logfile
* @param {number} [bufferSize=0] Default Buffer-Size. If > 0 we will write the log with buffering.
* @backend **Only in Nodejs available**
2021-05-21 17:21:53 +00:00
*/
2022-03-18 08:06:45 +00:00
export function useLogFile(
pathToFile = DEFAULT_FILE,
bufferSize = 100
): () => Promise<void> {
2021-05-21 17:21:53 +00:00
const logger = getCentralNopeLogger();
let bufferSizeToUse = bufferSize;
2021-05-21 17:21:53 +00:00
// Define a function, that will write the content of the Buffer to our
// file.
2021-07-29 14:07:32 +00:00
const writeBufferToFile = function (cb: () => void = null) {
const textToStore = "\n" + buffer.join("\n");
2021-05-21 17:21:53 +00:00
readyToWrite = false;
// Now lets start to write the Fil.e
writeFile(
pathToFile,
textToStore,
{
encoding: "utf-8",
2021-12-04 07:25:26 +00:00
flag: "a",
2021-05-21 17:21:53 +00:00
},
(err) => {
if (err) {
console.error(err);
} else {
readyToWrite = true;
2021-07-29 14:07:32 +00:00
2021-12-04 07:25:26 +00:00
if (typeof cb == "function") {
2021-07-29 14:07:32 +00:00
cb();
}
2021-05-21 17:21:53 +00:00
}
}
);
buffer = [];
};
let buffer: string[] = [];
let readyToWrite = false;
// Now every thing, is defined, so we are able to
// define our file.
const consoleLogger = getNopeLogger("file-logger");
createFile(pathToFile, "", { encoding: "utf-8" }).then(
// If our file has been created,
(_) => {
readyToWrite = true;
// Now make shure, that our inital buffer has been written
if (buffer.length > 0) {
writeBufferToFile();
}
}
);
logger.setHandler((msg, context) => {
// Else we extend our buffer:
const logAsString = [
new Date().toISOString(),
"-",
context.level.name,
"-",
context.name,
":",
// Try to store the Elements a String.
Object.values(msg)
.map((item) => {
try {
if (typeof item === "object")
return JSON.stringify(item, undefined, 2);
return item;
} catch (e) {
2021-12-04 07:25:26 +00:00
try {
return item.toString();
2021-12-04 07:25:26 +00:00
} catch (e) {
return item;
}
}
})
.join(" "),
].join(" ");
buffer.push(logAsString);
if (context.level.name === "ERROR") {
// We want errors to be rendered in here as well.
console.log(...formatMsgForConsole(msg, context));
}
if (bufferSizeToUse < buffer.length) {
if (readyToWrite) {
// Now if the Data is ready, lets write the
// buffer to the File.
writeBufferToFile();
} else if (_clearing) {
clearBufferAtEnd();
}
2021-05-21 17:21:53 +00:00
}
});
let _clearing = false;
2022-03-18 08:06:45 +00:00
const clearBufferAtEnd = async () => {
consoleLogger.info("Shutdown detected! Trying to Write the Buffer");
_clearing = true;
2021-05-21 17:21:53 +00:00
while (!readyToWrite || buffer.length > 0) {
if (readyToWrite) {
const promise = new Promise<void>((resolve, reject) => {
writeBufferToFile(resolve);
});
2022-03-18 08:06:45 +00:00
await promise;
} else await sleep(50);
}
2022-03-18 08:06:45 +00:00
bufferSizeToUse = 0;
2022-03-18 08:06:45 +00:00
};
2021-05-21 17:21:53 +00:00
2022-03-18 08:06:45 +00:00
return clearBufferAtEnd;
2021-05-21 17:21:53 +00:00
}