I have writtten code like below to log express logs.
const rfs = require("rotating-file-stream");
function formatDate() {
var d = new Date(),
month = '' + (d.getMonth() + 1),
day = '' + d.getDate(),
year = d.getFullYear();
hour = d.getHours();
if (month.length < 2)
month = '0' + month;
if (day.length < 2)
day = '0' + day;
if (hour.length < 2)
hour = '0' + hour
return [year, month, day, hour].join('-');
}
let log_directory = '/../logs/';
let log_date = formatDate()
let log_file_name = path.normalize(__dirname + log_directory + log_date, 'access.log');
let accessLogStream = rfs.createStream(log_file_name, {
size: "300M",
interval: "1d",
})
app.use(morgan(':date[iso] :method :url :body :headers :remote-addr :req[content-length] - :status :response-time ms - :res[content-length] ', { stream: accessLogStream }));
logs are getting stored out side of the project as expected.
But after rotation, the logs are storing inside the project with the below folder names
20200507-0943-01-
20200508-0943-01-
20200509-0943-01-
20200510-0943-01-
20200511-0943-01-
20200512-0943-01-
20200513-0944-01-
package.json
package-lock.json
public
routes
scripts
services
app.js
I don't want these folders created inside the project. Is there any way to handle this?
First of all you are using a static file name as filename parameter of createStream function and you are doing some computation on date to have your resulting file name.
Please note that the computation on date happens only once, before calling the createStream function. In order to do computation on date happening at each rotation you should use a filename generator function. Details can be found in readme.
More than this it seems there is a bug in this line: path.normalize accepts only one parameter.
let log_file_name = path.normalize(__dirname + log_directory + log_date, 'access.log');
Last, to specify a directory for logging, path option should be enough.
If I argued correctly your intentions, following code should solve all the problems
const rfs = require("rotating-file-stream");
function formatDate(d) {
var month = '' + (d.getMonth() + 1),
day = '' + d.getDate(),
year = d.getFullYear(),
hour = d.getHours();
if (month.length < 2)
month = '0' + month;
if (day.length < 2)
day = '0' + day;
if (hour.length < 2)
hour = '0' + hour;
return [year, month, day, hour].join('-');
}
function log_file_name(time, index) {
if (!time) return 'access.log';
return [formatDate(time), index, 'access.log'].join('-');
}
let accessLogStream = rfs.createStream(log_file_name, {
size: "300M",
interval: "1d",
path: '/../logs/'
});
Related
I am trying to find the oldest folder in a directory of my nodejs app.
Right now I get the folder names by fs.readdirSync and the I try to run through the mtime in a for-loop with the fs.stat function. But it does not return any values.
cron.schedule('* * * * *', () => {
folders = fs.readdirSync(__dirname + '/uploads/');
var oldestTime;
var oldest;
for (var i = 0; i < folders.length; i++) {
let stats = fs.statSync(folders[i]);
if (oldestTime == undefined || stats.mtime < oldestTime) {
oldestTime = stats.mtime;
oldest = folders[i];
}
}
console.log("oldest folder name is:", oldest)
}
Is there a better way?
Thank you so much!
You use the asynchronous version of fs.stat(). Try the synchronous (callback-free) fs.statSync() instead.
And don't forget that readdir returns results named . for the current directory and .. for the parent directory. You may want to exclude those from your mtime search.
And please spend some time reading up on the Javascript asynchronous programming model.
folders = fs.readdirSync(__dirname + "/uploads");
var oldestTime;
var oldest;
for (var i = 0; i < folders.length; i++) {
let stats = fs.statSync(__dirname + "/uploads/" + folders[i]);
if (oldestTime == undefined || stats.mtime < oldestTime) {
oldestTime = stats.mtime;
oldest = folders[i];
}
}
console.log("oldest folder name is:", oldest)
or use sort to get the oldest one:
const fs = require('fs');
const cron = require("cron");
var job = new cron.CronJob('* * * * * *', function () {
const folders = fs.readdirSync(__dirname + "/uploads");
var oldest = folders.sort((a, b) => fs.statSync(__dirname + '/uploads/' + a).mtime - fs.statSync(__dirname + '/uploads/' + b).mtime)[0];
console.log("oldest folder name is:", oldest)
});
job.start();
I want to extract the original name and date-taken from m2ts files in Node.
I found some dead code (m2ts-parser) using the package "packet". Though I'm too novice to really understand. But I want to learn :-)
So can anyone tell me how to extract the original filename and original creation date of the m2ts file (in node, but any pseudo code will do :-)
Thanks
update
I found - based on the answer of #aergistal a partial solution.
I am able to extract the Date/Time original from an m2ts file. Tested only on a Canon and Panasonic file:
var fs = require('fs');
fs.open('C:/temp/28685338476.mts', 'r', function (status, fd) {
if (status) {
console.log(status.message);
return;
}
var chunk = new Buffer(10000);
var syncFound = false;
var i, l;
fs.read(fd, chunk, 0, 10000, 0, function (err, num) {
for (i = 0, l = chunk.length; i < l; i++) {
if (chunk[i] === 0x47) {
syncFound = true;
}
if (syncFound) {
if (chunk[i] === 0x66 && chunk[i + 1] === 0x4D && chunk[i + 2] === 0x44 && chunk[i + 3] === 0x50 && chunk[i + 4] === 0x4D) {
console.log("GOT 'MDPM' at byte ", i);
var yy = chunk[i + 8].toString(16) + chunk[i + 9].toString(16);
var MM = chunk[i + 10].toString(16);
var dd = chunk[i + 12].toString(16);
var hh = chunk[i + 13].toString(16);
var mm = chunk[i + 14].toString(16);
var ss = chunk[i + 15].toString(16);
var timeStamp = yy + "/" + MM + "/" + dd + " " + hh + ":" + mm + ":" + ss;
console.log("TimeStamp: "+ timeStamp);
return timeStamp;
}
}
}
});
});
There is no such information in the MPEG-TS container.
This kind of metadata might be included in one of the elementary streams in which case its location will be different for every stream type. To make things worse there's no common standard even for the same type.
For example if your m2ts file contains a H.264 video stream such metadata might be found within the Supplemental Enhancement Information (SEI) if provided. The structure is described in the H.264 standard.
Once you know where the data is you will need to find out what format it uses. One example is the Modified Digital Video Pack Metadata (MDPM) which is supported by the exiftool and might contain a DateTimeOriginal tag. Example.
Of course, the metadata might not be present at all or stored in an auxiliary file.
I have this code that search new doc in drive folder, and send files via email
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var email = "xxx#gmail.com";
var timezone = ss.getSpreadsheetTimeZone();
var today = new Date();
var oneDayAgo = new Date(today.getTime() - 1 * 24 * 60 * 60 * 1000);
var startTime = oneDayAgo.toISOString();
var search = '(trashed = false or trashed = false) and (modifiedDate > "' + startTime + '")';
var folder1 = DriveApp.getFoldersByName('SaveToPDF').next();
var files1 = folder1.searchFiles(search);
var row = "", count=0;
while( files1.hasNext() ) {
var file1 = files1.next();
var fileName = file1.getName();
var fileURL = file1.getUrl();
var lastUpdated = Utilities.formatDate(file1.getLastUpdated(), timezone, "yyyy-MM-dd HH:mm");
var dateCreated = Utilities.formatDate(file1.getDateCreated(), timezone, "yyyy-MM-dd HH:mm")
row += "<li>" + lastUpdated + " <a href='" + fileURL + "'>" + fileName + "</a></li>";
sheet.appendRow([dateCreated, lastUpdated, fileName, fileURL]);
count++;
}
if (row !== "") {
row = "<p>" + count + " file(s) have changed in your Google Drive in the past 24 hours. Here's the list:</p><ol>" + row + "</ol>";
row += "<br><small>To stop these notifications, please <a href='" + ss.getUrl() + "'>click here</a> and choose <em>Uninstall</em> from the Drive Activity menu.<br/></small>";
MailApp.sendEmail(email, "Google Drive - File Activity Report", "", {htmlBody: row, cc: "xxx#gmail.com"} );
}
I need to convert sheet files to XLSX format before send.
Can someone help me?
Thanks
You can follow this tutorial on how to convert the current Google Spreadsheet to Excel XLSX format and then emails the file as an attachment to the specified user using getGoogleSpreadsheetAsExcel() method.
function getGoogleSpreadsheetAsExcel(){
try {
var ss = SpreadsheetApp.getActive();
var url = "https://docs.google.com/feeds/download/spreadsheets/Export?key=" + ss.getId() + "&exportFormat=xlsx";
var params = {
method : "get",
headers : {"Authorization": "Bearer " + ScriptApp.getOAuthToken()},
muteHttpExceptions: true
};
var blob = UrlFetchApp.fetch(url, params).getBlob();
blob.setName(ss.getName() + ".xlsx");
MailApp.sendEmail("amit#labnol.org", "Google Sheet to Excel", "The XLSX file is attached", {attachments: [blob]});
} catch (f) {
Logger.log(f.toString());
}
}
Here are some similar threads which might help:
Google apps script to email google spreadsheet excel version
Converting .xls to google spreadsheet in google apps script
I have a for loop in my nodejs code
const saveDocument = co.wrap(function *(documentData, user, locale) {
var now = moment();
var creationDateLongString = now.format("YYYYMMDDHHmmss");
var creationDateShortString = now.format("YYYYMMDD");
var outputChildFolder = documentData.code + '_' + creationDateLongString + '_' + documentCounter;
var outputFolder = config.files.incomingDocumentsDir + '/' + outputChildFolder;
++documentCounter;
yield fs.mkdir(outputFolder)
var xmlFileName = documentData.code + "-" + creationDateLongString + ".xml";
var pdfFileName = documentData.code + "-" + creationDateLongString + ".pdf";
const pages = [];
for(var index=0;index < documentData.pages.length; ++index) {
const page = documentData.pages[index];
var data = new Buffer(page, "base64");
var dataEncoding = imageType(data).mime === "image/png" ? "png" : "jpg";
var fileName = "page" + index + "." + dataEncoding;
var targetFilePath = outputFolder + "/" + fileName
yield fs.writeFile(targetFilePath,data);
pages.push(fileName);
}
...
}
What I don't understand is why in the above code page only gets assigned once, on the first iteration, and holds that same value during the other iterations. So if I have 5 pages I end up 5 times with the data of the first page in that variable.
I am running node 4 without any special arguments or postprocessor. Simply npm run ... which maps to a node src/main/myApp.js in my package.json
I am probably missing something simple here but I've never seen this before when doing client side ES6 code. The big difference of course being that the client side code goes through Babel + Webpack and the server side code is ran directly through node.
Small addendum: if you are wondering why the "old school" for syntax and not something along the lines of pages.forEach(...., it's because this is existing code where I just did a few minor modifications.
This will work as you are expecting in strict mode. Try adding...
"use strict";
You will only see this behavior in environments (like Node) that actually respect and enforce the keyword. Babel simply converts all let and const to var right now to provide ES5 compatibility. To demonstrate, take a look at this Babel example. You can see in the output that const has been changed to var
I need the current system datetime in the format "yyyy-mm-dd:hh:mm:ss".
https://stackoverflow.com/a/19079030/2663388 helped a lot.
new Date().toJSON() is showing "2014-07-14T13:41:23.521Z"
Can someone help me to extract "yyyy-mm-dd:hh:mm:ss" from "2014-07-14T13:41:23.521Z"?
Seems that there is no good way to do it with original code unless using Regex. There are some modules such as Moment.js though.
If you are using npm:
npm install moment --save
Then in your code:
var moment = require('moment');
moment().format('yyyy-mm-dd:hh:mm:ss');
That may be much easier to understand.
What about:
new Date().toString().replace(/T/, ':').replace(/\.\w*/, '');
Returns for me:
2014-07-14:13:41:23
But the more safe way is using Date class methods which works in javascript (browser) and node.js:
var date = new Date();
function getDateStringCustom(oDate) {
var sDate;
if (oDate instanceof Date) {
sDate = oDate.getYear() + 1900
+ ':'
+ ((oDate.getMonth() + 1 < 10) ? '0' + (oDate.getMonth() + 1) : oDate.getMonth() + 1)
+ ':' + oDate.getDate()
+ ':' + oDate.getHours()
+ ':' + ((oDate.getMinutes() < 10) ? '0' + (oDate.getMinutes()) : oDate.getMinutes())
+ ':' + ((oDate.getSeconds() < 10) ? '0' + (oDate.getSeconds()) : oDate.getSeconds());
} else {
throw new Error("oDate is not an instance of Date");
}
return sDate;
}
alert(getDateStringCustom(date));
Returns in node.js:
/usr/local/bin/node date.js 2014:07:14:16:13:10
And in Firebug:
2014:07:14:16:14:31
Install moment using
npm install moment --save
And in your code import the moment like this.
var moment = require('moment')
var created = moment().format('YYYY-MM-DD hh:mm:ss')
Though other answers are helpful I found the following code is working for me.
var d = new Date();
console.log(d.toJSON().slice(0,19).replace('T',':'));
The output on console is: 2014-07-15:06:10:16.
I am using Node.js Express on Ubuntu.
Cleaner version of #Bernhard code using padStart and without deprecated getYear
function getCurrentDateTimeString() {
const date = new Date();
return date.getFullYear() + '-' +
(date.getMonth() + 1).toString().padStart(2, '0') + '-' +
date.getDate().toString().padStart(2, '0') + ':' +
date.getHours().toString().padStart(2, '0') + ':' +
date.getMinutes().toString().padStart(2, '0') + ':' +
date.getSeconds().toString().padStart(2, '0');
}
console.log(getCurrentDateTimeString());
Explicity call each part of the Date:
function formatDate(date) {
return [date.getFullYear(), date.getMonth() + 1, date.getDate()].join('-') + ':' +
[date.getHours(), date.getMinutes(), date.getSeconds()].join(':');
}
function formatDatePart(part) {
return part < 10 ? ("0" + part) : part;
}
You can see an example on this fiddle.
Correct way is this
var moment = require('moment');
moment().format('Y-M-D H:m:s');
You can do it using toLocaleString() method in node.js
let date = new Date('2014-07-14T13:41:23.521Z');
console.log(date.toLocaleString('en-US'));
//Converting current date time without timezone
date = new Date()
console.log(date.toLocaleString('en-US'));