How can I make NodeJS's console.log always print output within a single line no matter what? - visual-studio-code

Is there any way to format the JSON logged through console.log in the terminal?
I'm logging a lot of debug data and if the the logged data exceeds a certain length, the terminal logs it prettified in many lines. I'd like to change it to log in one line, no matter the length of the data. Is there any way to do that?
In summary, I want to change this log style:
[12:34:56][DEBUG][CODE] - {
data: {
action: 'action',
url: '/path/to/my/api?variableOne=valueOne&variableTwo=valueTwo'
}
}
To this log style:
[12:34:56][DEBUG][CODE] - { data: { action: 'action', url: '/path/to/my/api?variableOne=valueOne&variableTwo=valueTwo' } }

Is there any way to format the JSON logged through console.log in the terminal?
Yes there is. Create a custom console object. See the docs for how to do that and what options you can specify. In particular, see also the inspectOptions docs.
The particular inspectOptions option you are looking for are breaklength and compact:
breakLength: <integer> The length at which input values are split across multiple lines. Set to Infinity to format the input as a single line (in combination with compact set to true or any number >= 1). Default: 80.
compact: <boolean> | <integer> Setting this to false causes each object key to be displayed on a new line. It will break on new lines in text that is longer than breakLength. If set to a number, the most n inner elements are united on a single line as long as all properties fit into breakLength. Short array elements are also grouped together. For more information, see the example below. Default: 3.
So since you asked
I'd like to change it to log in one line, no matter the length of the data
Then you probably want to do something like this:
const { Console } = require('node:console')
console = new Console({
stdout: process.stdout,
stderr: process.stderr,
// ignoreErrors, colorMode, groupIndentation
inspectOptions: {
// ...
breakLength: Infinity,
compact: true,
// ...
}
});
And then you can test it with console.log({a:1,b:2,c:3,hello:"world!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"});.
You can also just use the util.inspect function on specific objects you want to make a formatted string for, and then do console.log on the default global console object, passing the returned string.

Related

My google sheets function does the job when run from editor but gives different outcome when trigered by Form submit

I have a google form and a sheet that collects the responses which of course always appear at the bottom. I have been using the following script to copy the last response (which is always on the last row) from the Response sheet (Form Responses 2) to row two of another sheet (All Responses). When run by a trigger on Form Submit the script inserts a blank row into All Responses, then the copied values into another row above the blank row. Please can you help and tell me why and how I might change the script so the blank row is not added:
function CopyLastrowformresponse () {
var ss = SpreadsheetApp.getActive();
var AR = ss.getSheetByName("All Responses");
var FR = ss.getSheetByName("Form responses 2");
var FRlastrow = FR.getLastRow();
AR.insertRowBefore(2);
FR.getRange(FRlastrow, 1, FRlastrow, 22).copyTo(AR.getRange("A2"), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
}
A few things could be going on here.
You're getting a number of rows equal to FRlastrow, when I think you only want to be getting 1 row.
Apps Script has buggy behavior with onFormSubmit() triggers, so you may to check duplicate triggers (see this answer).
The script isn't fully exploiting the event object provided by onFormSubmit(). Specifically, rather than getting the last row from one sheet, you could use e.values, which is the same data.
I would change the script to be something like this:
function CopyLastrowformresponse (e) {
if (e.values && e.values[1] != "") { // assuming e.values[1] (the first question) is required
SpreadsheetApp.getActive()
.getSheetByName("All Responses")
.insertRowBefore(2)
.getRange(2, 1, 1, e.values.length)
.setValues([e.values]);
}
}
But, ultimately, if all you want to do is simply reverse the order of the results, then I'd ditch Apps Script altogether and just use the =SORT() function.
=SORT('Form responses 2'!A:V, 'Form responses 2'!A:A, FALSE)

Reading INI file is not working using IniRead in AHK

I am trying to read a INI file and get the values from it using AHK. However, the read is not successful and I am getting the default value from the call every time.
Here is the code I used :-
ReadIniFile(IniFileName, SectionName, KeyName,ByRef Value)
{
If FileExist(IniFileName)
{
MsgBox File found ; this comes
}
IniRead, Value, IniFileName, SectionName, KeyName , Default
MsgBox %Value% %IniFileName% %KeyName% %SectionName% ; Value comes as 'Default'
}
The output is :-
Default C:\Users\barmans\Desktop\ECU.h ININame GeneralSettings
The function call is :
ReadIniFile(HeaderFileName, "GeneralSettings", "ININame", AutoTestScript)
The INI is in format :-
[GeneralSettings]
ECU=ABS8_B
ININame=ABS8_B_Test.ini
KBDiagPath=C:\KBApps\Knorr-Bremse\KB Diag
RunCount=0
[LogSettings]
LogFileName=ABS8_B_Report.log
TraceLevel=1
Any guidance is appreciated.
As you did in MsgBox, you have to enclose your variables with % percent signs.
If the documentation tells you to state a "name", "value" or anything like that, you'll need an actual string or integer. Other than that, sometimes you're asked to state a "variable name", in which case you obviously must not use % - as in function calls.
So, your iniread will look like:
IniRead, Value, %IniFileName%, %SectionName%, %KeyName%, Default
for more detailed information, visit http://ahkscript.org/docs/Variables.htm. Tho I do not see anything about the use of variables in command there

How to log an element using protractor?

I'm trying to locate an element using protractor but I can't find it. To debug, I'd like to look at the element I did find and see which one it is. I have some code like this:
myElement.all(by.cssContainingText('.name', 'value')).then(function (elems) {
console.log(elems.length); <--- this line logs "2"
console.log(elems[1]); <--- this line logs "{ ptor_: ...."
elems[1].getInnerHtml().then(function(html){
console.log(html); <--- never gets here
}); });
How can I see what elements the all() method found?
Not sure if it's the best/most concise way, but you should be able to use map to loop over the elements, and use getOuterHtml() on each to access the HTML
myElement.all(by.cssContainingText('.name', 'value')).map(function(el) {
return el.getOuterHtml();
}).then(function(html) {
console.log(html);
});

What's wrong with my Meteor publication?

I have a publication, essentially what's below:
Meteor.publish('entity-filings', function publishFunction(cik, queryArray, limit) {
if (!cik || !filingsArray)
console.error('PUBLICATION PROBLEM');
var limit = 40;
var entityFilingsSelector = {};
if (filingsArray.indexOf('all-entity-filings') > -1)
entityFilingsSelector = {ct: 'filing',cik: cik};
else
entityFilingsSelector = {ct:'filing', cik: cik, formNumber: { $in: filingsArray} };
return SB.Content.find(entityFilingsSelector, {
limit: limit
});
});
I'm having trouble with the filingsArray part. filingsArray is an array of regexes for the Mongo $in query. I can hardcode filingsArray in the publication as [/8-K/], and that returns the correct results. But I can't get the query to work properly when I pass the array from the router. See the debugged contents of the array in the image below. The second and third images are the client/server debug contents indicating same content on both client and server, and also identical to when I hardcode the array in the query.
My question is: what am I missing? Why won't my query work, or what are some likely reasons it isn't working?
In that first screenshot, that's a string that looks like a regex literal, not an actual RegExp object. So {$in: ["/8-K/"]} will only match literally "/8-K/", which is not the same as {$in: [/8-K/]}.
Regexes are not EJSON-able objects, so you won't be able to send them over the wire as publish function arguments or method arguments or method return values. I'd recommend sending a string, then inside the publish function, use new RegExp(...) to construct a regex object.
If you're comfortable adding new methods on the RegExp prototype, you could try making RegExp an EJSON-able type, by putting this in your server and client code:
RegExp.prototype.toJSONValue = function () {
return this.source;
};
RegExp.prototype.typeName = function () {
return "regex";
}
EJSON.addType("regex", function (str) {
return new RegExp(str);
});
After doing this, you should be able to use regexes as publish function arguments, method arguments and method return values. See this meteorpad.
/8-K/.. that's a weird regex. Try /8\-K/.
A minus (-) sign is a range indicator and usually used inside square brackets. The reason why it's weird because how could you even calculate a range between 8 and K? If you do not escape that, it probably wouldn't be used to match anything (thus your query would not work). Sometimes, it does work though. Better safe than never.
/8\-K/ matches the string "8-K" anywhere once.. which I assume you are trying to do.
Also it would help if you would ensure your publication would always return something.. here's a good area where you could fail:
if (!cik || !filingsArray)
console.error('PUBLICATION PROBLEM');
If those parameters aren't filled, console.log is probably not the best way to handle it. A better way:
if (!cik || !filingsArray) {
throw "entity-filings: Publication problem.";
return false;
} else {
// .. the rest of your publication
}
This makes sure that the client does not wait unnecessarily long for publications statuses as you have successfully ensured that in any (input) case you returned either false or a Cursor and nothing in between (like surprise undefineds, unfilled Cursors, other garbage data.

Protovis - dealing with a text source

lets say I have a text file with lines as such:
[4/20/11 17:07:12:875 CEST] 00000059 FfdcProvider W com.test.ws.ffdc.impl.FfdcProvider logIncident FFDC1003I: FFDC Incident emitted on D:/Prgs/testing/WebSphere/AppServer/profiles/ProcCtr01/logs/ffdc/server1_3d203d20_11.04.20_17.07.12.8755227341908890183253.txt com.test.testserver.management.cmdframework.CmdNotificationListener 134
[4/20/11 17:07:27:609 CEST] 0000005d wle E CWLLG2229E: An exception occurred in an EJB call. Error: Snapshot with ID Snapshot.8fdaaf3f-ce3f-426e-9347-3ac7e8a3863e not found.
com.lombardisoftware.core.TeamWorksException: Snapshot with ID Snapshot.8fdaaf3f-ce3f-426e-9347-3ac7e8a3863e not found.
at com.lombardisoftware.server.ejb.persistence.CommonDAO.assertNotNull(CommonDAO.java:70)
Is there anyway to easily import a data source such as this into protovis, if not what would the easiest way to parse this into a JSON format. For example for the first entry might be parsed like so:
[
{
"Date": "4/20/11 17:07:12:875 CEST",
"Status": "00000059",
"Msg": "FfdcProvider W com.test.ws.ffdc.impl.FfdcProvider logIncident FFDC1003I",
},
]
Thanks, David
Protovis itself doesn't offer any utilities for parsing text files, so your options are:
Use Javascript to parse the text into an object, most likely using regex.
Pre-process the text using the text-parsing language or utility of your choice, exporting a JSON file.
Which you choose depends on several factors:
Is the data somewhat static, or are you going to be running this on a new or dynamic file each time you look at it? With static data, it might be easiest to pre-process; with dynamic data, this may add an annoying extra step.
How much data do you have? Parsing a 20K text file in Javascript is totally fine; parsing a 2MB file will be really slow, and will cause the browser to hang while it's working (unless you use Workers).
If there's a lot of processing involved, would you rather put that load on the server (by using a server-side script for pre-processing) or on the client (by doing it in the browser)?
If you wanted to do this in Javascript, based on the sample you provided, you might do something like this:
// Assumes var text = 'your text';
// use the utility of your choice to load your text file into the
// variable (e.g. jQuery.get()), or just paste it in.
var lines = text.split(/[\r\n\f]+/),
// regex to match your log entry beginning
patt = /^\[(\d\d?\/\d\d?\/\d\d? \d\d:\d\d:\d\d:\d{3} [A-Z]+)\] (\d{8})/,
items = [],
currentItem;
// loop through the lines in the file
lines.forEach(function(line) {
// look for the beginning of a log entry
var initialData = line.match(patt);
if (initialData) {
// start a new item, using the captured matches
currentItem = {
Date: initialData[1],
Status: initialData[2],
Msg: line.substr(initialData[0].length + 1)
}
items.push(currentItem);
} else {
// this is a continuation of the last item
currentItem.Msg += "\n" + line;
}
});
// items now contains an array of objects with your data