Date in response JSON is different than in database - json

I have sails.js application.
When I add record to my MySQL database there is field createdAt - type dateTime.
In MySql console createdAt value looks like Wed Mar 25 2015 00:00:00 GMT+0100
When I try to get this data as JSON using sails.js controller I get
2015-03-24T23:00:00.000Z - which is 1 hour elier?
My system time zone is GMT +1.
How can I get the same time in db and JSON rsponse?
'list': function (req, res, next) {
Tests.find().exec(function (err, tests) {
if (err) res.json({ error: 'DB error' }, 500);
if (tests) {
_.each(tests, function (data) {
console.log("Date: " + JSON.stringify(data.createdAt)+" "+data.createdAt);
})
res.status(200).json(tests);
}
});
And console output is:
Date: "2015-03-10T14:28:51.000Z" Tue Mar 10 2015 15:28:51 GMT+0100
Date: "2015-03-16T10:25:34.000Z" Mon Mar 16 2015 11:25:34 GMT+0100
Date: "2015-03-16T11:27:23.000Z" Mon Mar 16 2015 12:27:23 GMT+0100
Date: "2015-03-16T11:33:39.000Z" Mon Mar 16 2015 12:33:39 GMT+0100
Date: "2015-03-16T11:34:41.000Z" Mon Mar 16 2015 12:34:41 GMT+0100
Date: "2015-03-16T12:13:21.000Z" Mon Mar 16 2015 13:13:21 GMT+0100
Date: "2015-03-16T13:54:03.000Z" Mon Mar 16 2015 14:54:03 GMT+0100
It all happends while converting to JSON - still dont know how to fix it.

JSON.stringify(data.createdAt) is equal to data.createdAt.toJSON() and it is equal to data.createdAt.toISOString()
data.createdAt is equal to data.createdAt.toString()
the time value is equal; toString() returns it according your time zone, while toISOString() in GMT.
to get the Date from JSON string use conversion function as 2nd parameter of JSON.parse(), you can use the regexp rx = /([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})\.([0-9]{3})Z/ to check the date ISO format and then convert it to date d = new Date(str)

What is the type of createdAt in your Mysql database? Is it Date? If yes try setting it to varchar. And if you need to manipulate it or format it you can use moment js.

Related

SerializationException when attempting to insert Log into Cloudwatch via API Gateway

We wanted to leverage an existing API Gateway and alter the destination of some errors in an application not hosted in AWS from an RDS to a CloudWatch log group and stream but when testing it I get a SerializationException every time
The model of the data coming into the gateway is
{
"Message":"foo",
"StackTrace":"bar",
"Category": "example"
"CustomData":{"foo":"bar","fee","fum"},
"Timestamp": 1564043651175
}
The timestamp was added as it is required to insert a CloudWatch log as shown [here]: https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_PutLogEvents.html
The following is some of the CloudFormation yaml that defines the API Gateway which is making the requests
Uri:
Fn::Join:
- ''
- - 'arn:aws:apigateway:'
- !Ref AWS::Region
- ":logs:action/PutLogEvents"
RequestTemplates:
application/json: !Sub |
#set($inputRoot = $input.path('$'))
#set($context.requestOverride.header['X-Amz-Target'] = "Logs_20140328.PutLogEvents")
#set($context.requestOverride.header['Content-Type'] = "application/x-amz-json-1.1")
{
"logGroupName": "${Prefix}-err-group"
"logStreamName": "${Prefix}-app-errors"
"logEvents": [
{
"message": "message: $inputRoot.Message, stackTrace: $inputRoot.StackTrace, category: $inputRoot.Category, customData: $inputRoot.CustomData",
"timestamp": "$inputRoot.Timestamp"
}
]
}
The API method deploys successfully and when testing it in the console using the Method Test and the model above I get the following output from the test
Thu Jul 25 08:14:24 UTC 2019 : Starting execution for request: 364e53c8-aeb4-11e9-91f6-ab8c0812e717
Thu Jul 25 08:14:24 UTC 2019 : HTTP Method: POST, Resource Path: /
Thu Jul 25 08:14:24 UTC 2019 : Method request path: {}
Thu Jul 25 08:14:24 UTC 2019 : Method request query string: {}
Thu Jul 25 08:14:24 UTC 2019 : Method request headers: {}
Thu Jul 25 08:14:24 UTC 2019 : Method request body before transformations: {
"Message": "Example Message",
"StackTrace": "Example StackTrace",
"Category": "Category1",
"CustomData": {"GUID": "17e332e5-9d03-4e0d-83b1-874f62cb33bb","One": "1","Version": "28.1.1.0","ErrorId": "1212"},
"Timestamp": 1564040369451
}
Thu Jul 25 08:14:24 UTC 2019 : Request validation succeeded for content type application/json
Thu Jul 25 08:14:24 UTC 2019 : Request parameter overrides:
Add X-Amz-Target: Logs_20140328.PutLogEvents
Add Content-Type: application/x-amz-json-1.1
Thu Jul 25 08:14:24 UTC 2019 : Endpoint request URI: https://logs.eu-west-2.amazonaws.com/?Action=PutLogEvents
Thu Jul 25 08:14:24 UTC 2019 : Endpoint request headers: {Authorization=<Redacted>, X-Amz-Date=20190725T081424Z, x-amzn-apigateway-api-id=<Redacted>, Accept=application/json, User-Agent=AmazonAPIGateway_<Redacted>, X-Amz-Security-Token=<Redacted>[TRUNCATED]
Thu Jul 25 08:14:24 UTC 2019 : Endpoint request body after transformations: {
"logGroupName": "test-err-group"
"logStreamName": "test-app-errors"
"logEvents": [
{
"message": "message: Example Message, stackTrace: Example StackTrace, category, Category1, customData: {GUID=17e332e5-9d03-4e0d-83b1-874f62cb33bb,One=1,Version=28.1.1.0,ErrorId=1212}",
"timestamp": "1564040369451"
}
]
}
Thu Jul 25 08:14:24 UTC 2019 : Sending request to https://logs.eu-west-2.amazonaws.com/?Action=PutLogEvents
Thu Jul 25 08:14:24 UTC 2019 : Received response. Status: 400, Integration latency: 7 ms
Thu Jul 25 08:14:24 UTC 2019 : Endpoint response headers: {x-amzn-RequestId=3655f4fb-aeb4-11e9-8498-591aad10a10c, Content-Type=application/x-amz-json-1.1, Content-Length=35, Date=Thu, 25 Jul 2019 08:14:23 GMT, Connection=close}
Thu Jul 25 08:14:24 UTC 2019 : Endpoint response body before transformations: {"__type":"SerializationException"}
Thu Jul 25 08:14:24 UTC 2019 : Method response body after transformations: {"__type":"SerializationException"}
Thu Jul 25 08:14:24 UTC 2019 : Method response headers: {X-Amzn-Trace-Id=Root=1-5d3964e0-291c033c3040ef301afc81c5, Access-Control-Allow-Origin=*, Content-Type=application/json}
Thu Jul 25 08:14:24 UTC 2019 : Successfully completed execution
Thu Jul 25 08:14:24 UTC 2019 : Method completed with status: 200
This still occurs when I replace the more complex json request body with a simple string. I found [this post]: Getting SerializationException while trying to PutLogEvents on cloudwatch using golang when someone had the same exception but it was due to a problem with their GoLang rather than going through API
Turns out I was missing 2 commas after logGroupName and logStreamName. Blinded by looking at it for too long

I want store web log that using morgan and express to json file

I want store JSON file each like form
[
{
"remote-addr" : "127.0.0.1",
"date" : " 2018.07.28"
}
]
and i use this code
var format=json(
':remote-addr:date'
);
app.use(logger({
format:format,
stream: fs.createWriteStream('log.json')
}));
i use this code and get
{"remote-addr":"::ffff:127.0.0.1","date":"Sat, 28 Jul 2018 04:38:41 GMT"}
{"remote-addr":"::ffff:127.0.0.1","date":"Sat, 28 Jul 2018 04:38:41 GMT"}
{"remote-addr":"::ffff:127.0.0.1","date":"Sat, 28 Jul 2018 04:38:42 GMT"}
{"remote-addr":"::ffff:127.0.0.1","date":"Sat, 28 Jul 2018 04:38:48 GMT"}
this is json file but there no [ ] and ,
how to get json file??
Technically Morgan does not allow you to do this, because it's entire purpose is to write one standard access.log line per request (credits to Douglas Wilson for pointing that out).
Yes, you can hack around the single log line, like you did, which makes it a valid JSON line. However, in order to make your log.json file to be a valid JSON as well, the only way I can think of is to implement some kind of post-processing to the file.
Here's how the post-processing will look like: First, you need to read line by line the file. Then, create your valid JSON. Finally - save it in a separate file (or override the log.json anyways).
Here's how I did it. Input: your current log.json file:
{"remote-addr":"::ffff:127.0.0.1","date":"Sat, 28 Jul 2018 04:38:41 GMT"}
{"remote-addr":"::ffff:127.0.0.1","date":"Sat, 28 Jul 2018 04:38:41 GMT"}
{"remote-addr":"::ffff:127.0.0.1","date":"Sat, 28 Jul 2018 04:38:42 GMT"}
{"remote-addr":"::ffff:127.0.0.1","date":"Sat, 28 Jul 2018 04:38:48 GMT"}
The post-processing script I wrote:
const fs = require('fs');
// Since Node.js v0.12 and as of Node.js v4.0.0, there is a stable
// readline core module. That's the easiest way to read lines from a file,
// without any external modules. Credits: https://stackoverflow.com/a/32599033/1333836
const readline = require('readline');
const lineReader = readline.createInterface({
input: fs.createReadStream('log.json')
});
const realJSON = [];
lineReader.on('line', function (line) {
realJSON.push(JSON.parse(line));
});
lineReader.on('close', function () {
// final-log.json is the post-processed, valid JSON file
fs.writeFile('final-log.json', JSON.stringify(realJSON), 'utf8', () => {
console.log('Done!');
});
});
Result: the final-log.json file, which is a valid JSON (I validated it with jsonlint, all good).
[{
"remote-addr": "::ffff:127.0.0.1",
"date": "Sat, 28 Jul 2018 04:38:41 GMT"
}, {
"remote-addr": "::ffff:127.0.0.1",
"date": "Sat, 28 Jul 2018 04:38:41 GMT"
}, {
"remote-addr": "::ffff:127.0.0.1",
"date": "Sat, 28 Jul 2018 04:38:42 GMT"
}, {
"remote-addr": "::ffff:127.0.0.1",
"date": "Sat, 28 Jul 2018 04:38:48 GMT"
}]

Server-sent event received after 3-4 seconds

While reading about Server-Sent Events from this page, I got confused about the timing of events. Basically, the example shown has a PHP script sending the system time to the web page:
<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
$time = date('r');
echo "data: The server time is: {$time}\n\n";
flush();
?>
While the page receives and renders it:
if(typeof(EventSource) !== "undefined") {
var source = new EventSource("demo_sse.php");
source.onmessage = function(event) {
document.getElementById("result").innerHTML += event.data + "<br>";
};
} else {
document.getElementById("result").innerHTML = "Sorry, your browser does not support server-sent events...";
}
My confusion is that the server seems to be sending messages every 3-4 seconds:
The server time is: Tue, 20 Sep 2016 11:55:12 -0400
The server time is: Tue, 20 Sep 2016 11:55:16 -0400
The server time is: Tue, 20 Sep 2016 11:55:20 -0400
The server time is: Tue, 20 Sep 2016 11:55:23 -0400
The server time is: Tue, 20 Sep 2016 11:55:28 -0400
The server time is: Tue, 20 Sep 2016 11:55:32 -0400
The server time is: Tue, 20 Sep 2016 11:55:35 -0400
The server time is: Tue, 20 Sep 2016 11:55:39 -0400
The server time is: Tue, 20 Sep 2016 11:55:43 -0400
The server time is: Tue, 20 Sep 2016 11:55:46 -0400
The server time is: Tue, 20 Sep 2016 11:55:50 -0400
The server time is: Tue, 20 Sep 2016 11:55:53 -0400
The server time is: Tue, 20 Sep 2016 11:55:57 -0400
The server time is: Tue, 20 Sep 2016 11:56:01 -0400
The server time is: Tue, 20 Sep 2016 11:56:04 -0400
The server time is: Tue, 20 Sep 2016 11:56:08 -0400
The server time is: Tue, 20 Sep 2016 11:56:12 -0400
The server time is: Tue, 20 Sep 2016 11:56:15 -0400
However, I don't see this delay either at the server end or at the client end. Is it the network lag between the website's server and my browser? Or is it something else?
Default retry is 3 seconds as shown on http://www.html5rocks.com/en/tutorials/eventsource/basics/
Check out the "Controlling the Reconnection-timeout section" on that link.
You may customize it by sending a line retry:100
to enforce just 100ms retry time interval.

WWW.responseHeader["STATUS"] does not exists

I already asked on answers.unity3d but as there is no response I'll ask on SO too..
I'm not able to retrieve the http status of a response on the WWW object on Windows Phone 8 and Windows RT 8.1 (while it's ok on IOS/Android).
www.responseHeader["STATUS"] does not exists and the hidden field _responseHeaderString does not contain as first line
HTTP/1.1 200 OK
responseHeaderString :
Server: nginx
Date: Wed, 21 Oct 2015 07:44:36 GMT
Last-Modified: Mon, 07 Sep 2015 11:43:46 GMT
Connection: keep-alive
Expires: Fri, 20 Nov 2015 07:44:36 GMT
Cache-Control: max-age=2592000
Cache-Control: public
responseHeader :
{
"SERVER" : "nginx"
"DATE" : "Wed, 21 Oct 2015 07:44:36 GMT"
"LAST-MODIFIED": "Mon, 07 Sep 2015 11:43:46 GMT"
"CONNECTION" : "keep-alive"
"EXPIRES" : "Fri, 20 Nov 2015 07:44:36 GMT"
"CACHE-CONTROL": "public"
}
Sample code to reproduce : (tested on an empty new project)
WWW www = new WWW("http://www.google.com");
yield return www;
Debug.Log("Google Status : " + www.responseHeaders.ContainsKey("STATUS")); // False
Debug.Log(www.text); // <doctype ...
Debug.Log(www.responseHeaders["STATUS"]); // KeyError
Am I missing something or is there someone that can confirm this as a bug ?
Edit:
Still not able to retrieve the http status with the latest 5.3
Your network server is probably responding with a different (unexpected) response to each device. For various reasons such as the user agent string, which could lead the WWW class to not get the STATUS.
Firstly, I would install a proxy so you can see exactly what the phone sends and what the server raw response is. Either Charles Proxy (mac/windows) or Fiddler (windows) are great.
Here is the actual code that Unity WWW class is using to generate status:
if (num++ == 0 && text.StartsWith("HTTP"))
{
dictionary["STATUS"] = text;
}
Ref: https://github.com/MattRix/UnityDecompiled/blob/master/UnityEngine/UnityEngine/WWW.cs#L483
From the proxy it should be clear what is happening. If not, post the request and response here (as raw).
Try reading the www.error before looking for the STATUS header.
// Construct the response object
string error = www.error;
if (error == null) {
if (www.responseHeaders.ContainsKey("STATUS")) {
string [] status=www.responseHeaders["STATUS"].Split(' ');
if (status.Length>2 && status[2] != "OK") {
error = www.responseHeaders["STATUS"];
}
}
}

Array items sorting and editing with MXML AS3 (in practical case)?

I have an array with lots of items with same names like
CloudObserverCMSStub edited
CloudObserverCMSStub edited
CloudObserverCMSStub created
CloudObserverCMSStub2 edited
CloudObserverCMSStub2 edited
CloudObserverCMSStub2 created
and different related to names dates for each item in such format
Wed, 17 Mar 2010 22:32:09 GMT
Wed, 17 Mar 2010 22:32:07 GMT
Wed, 17 Mar 2010 22:32:02 GMT
Wed, 17 Mar 2010 22:31:02 GMT
Wed, 17 Mar 2010 21:32:02 GMT
Wed, 15 Mar 2009 22:32:02 GMT
I want to sort them so that I get only the latest ones in such format (with no such stuff like edited or created)
CloudObserverCMSStub | Wed, 17 Mar 2010 22:32:09 GMT
CloudObserverCMSStub2 | Wed, 17 Mar 2010 22:31:02 GMT
So I want a new array of 2 items from for example 6 how to do such thing?
You create an object, store the common names as the keys, and use dates as values. Then you can compare the dates and replace it if the date is more recent. Eg:
var obj:Object;
for(var element in array) // I honestly forget AS3 syntax.
{
if(obj[element.name] == null)
{
obj[element.name] = element;
}
else
{
if(obj[element.name].date > element.date)
{
obj[element.name] = element;
}
}
}
Then just enumerate all the elements in obj.