So i am running some experiments w/ message logging policy. It isnt that hard to use. it seems to support a couple of commercial log consolidation systems out of the box (but not Logstash - interestingly enough). Hooking up custom logs to logstash should not be too much of a problem if i want to use the file system option (the semi insanity of the pathing system is going to be a bit of a configuration disaster - but I will solve that later) Heres where im stuck...
i seem to be able to output a timestamp like this:
1377112607413
or like this:
Wed, 21 Aug 2013 19:16:47 UTC
but not in ISO format (like this):
2015-07-10 21:07:38,935
If there is a way to output this i would love it. I can work around it if i need to - but its become pretty standard around here and i have to ask if its available as output.
Also - Line Breaks... the output im sending right now seems to be .. never mind - I figured out how to add a line break at the end of each message...
Solved! Go to Solution.
Hi @Benjamin Goldman. You can leverage the following code executed by a JavaScript policy and store it in a context variable, which then can be used by the message logging policy like this:
var isoDate = new Date().toISOString(); context.setVariable("isoDate", isoDate);
Then from the Message logging policy:
<MessageLogging name="LogToSyslog">> <Syslog> <Message>[3f509b58 tag="{organization.name}.{apiproxy.name}.{environment.name}"] {isoDate}</Message> <Host>logs-01.loggly.com</Host> <Port>514</Port> <Protocol>TCP</Protocol> </Syslog> </MessageLogging>
Credits to @Sudheer Gopalam.
Hope it helps!
Hi @Benjamin Goldman. You can leverage the following code executed by a JavaScript policy and store it in a context variable, which then can be used by the message logging policy like this:
var isoDate = new Date().toISOString(); context.setVariable("isoDate", isoDate);
Then from the Message logging policy:
<MessageLogging name="LogToSyslog">> <Syslog> <Message>[3f509b58 tag="{organization.name}.{apiproxy.name}.{environment.name}"] {isoDate}</Message> <Host>logs-01.loggly.com</Host> <Port>514</Port> <Protocol>TCP</Protocol> </Syslog> </MessageLogging>
Credits to @Sudheer Gopalam.
Hope it helps!
So i think i should modify my question - because while this will do what i asked above - it doesnt actually do what I want.
I dont want a timestamp. I want THE timestamp from the inbound request.
There are a couple of variables exposed in apigee related to start/end of both request and response. These are very much accurate in terms of when transactions are taking place. Both allow output of one of the two timestamp formats i mentioned above.
I bet i could do exactly the same thing but call that variable inside the javascript. I will experiment with that tomorrow. In the mean time im not going to accept the answer but give you points 🙂
When i test this - if it allows me to do what I need I will accept your answer and post my version of the solution in the comments (it will confuse people a bit - but you can then edit your answer and include my version in the quotes maybe? not sure)
Correct. You should be able to leverage system.timestamp instead then:
var isoDate = new Date(context.getVariable("system.timestamp")).toISOString(); context.setVariable("isoDate", isoDate);
I was hoping to be able to access {client.received.start.timestamp} - this way I could use similar variables later and make my logs a source of truth for troubleshooting.
It looks like it is returning no data. This variable is TRUTH as to when the request to the message processor starts - so it should be used for logging. a general timestamp isnt actually when the request starts, even if you put the javascript policy as the first entry.
No matter how this works out though - it is going to be messy to build enough timestamps to allow really detailed logging like this: i am going to have to not only have multiple log policies but potentially many many javascript policies... which is a shame - because there is a nice variable {client.received.start.timestamp} which i could use but it just doesnt provide me a usable format.
And this doesnt even begin to address the problems im going to have introducing this as a standard policy to all of the proxies on my system... and uf.. one problem at a time.
FYI - this is the best answer there is going to be! Thanks for your help.
Thanks. It's good to report these issues.
@arghya das - Are you aware of this issue?
var isoSystemTimeStamp = new Date(context.getVariable("system.timestamp")).toISOString(); context.setVariable("loggingIsoSystemTimeStamp", isoSystemTimeStamp);
works
var isoSystemTimeStamp = new Date(context.getVariable("client.received.start.timestamp")).toISOString(); context.setVariable("loggingIsoSystemTimeStamp", isoSystemTimeStamp);
does not work - returns nothing.
<figured out that it was a scope problem - misunderstood where this was available>
@Benjamin Goldman Can you email me your proxy and let me see what you are doing. Here's the bundle that I tried where I tried the exact same javascript as yours, and that's the only policy I have in the no target proxy. It seems to work fine for me.
So i went back and re-typed the entire statement again:
var isoSystemTimeStamp = new Date(context.getVariable("client.received.start.timestamp")).toISOString(); context.setVariable("loggingIsoSystemTimeStamp", isoSystemTimeStamp);
and i am now able to access the variable w/o it being empty.
gave you points because you forced me to fiddle with it more instead of moving on and using something other than what I wanted to.
A quick correction, a timestamp using a space separator between the date and hour is not the official specification, instead, the separator should be a "T". There are some exceptional circumstances where space is allowed, such as compatibility, but it should not be used in general. @Benjamin Goldman
how did you manage to obtain this date format "Wed, 21 Aug 2013 19:16:47 UTC" ?
Did you use an extra JavaScript policy for that?
Thanks in advance
Adding a new answer to an old question... you can now do this in AssignMessage.
<AssignMessage name='AM-FormatTime'> <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables> <AssignVariable> <Name>formatString1</Name> <Value>yyyy-MM-dd HH:mm:ss.SSS</Value> <!-- EEEE --> </AssignVariable> <AssignVariable> <Name>formattedTime</Name> <Template>{timeFormatUTCMs(formatString1,client.received.end.timestamp)}</Template> </AssignVariable> </AssignMessage>
I know it's old thread but does it work in Raise Fault?Looking for a simple timestamp in ISO format(2021-03-29T04:06:04.223Z) while raising fault.
Tried few combinations but doesn't seems to be working. Any suggestions?
https://docs.apigee.com/api-platform/reference/message-template-intro#spacesnotallowed
You should be able to use AssignVariable within RaiseFault. It looks like this:
<RaiseFault name='RF-1'> <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables> <UsePolicyNameAsFaultReason>true</UsePolicyNameAsFaultReason> <FaultResponse> <AssignVariable> <Name>formatString1</Name> <Value>yyyy-MM-dd HH:mm:ss.SSS</Value> <!-- EEEE --> </AssignVariable> <AssignVariable> <Name>formattedTime</Name> <Template>{timeFormatUTCMs(formatString1,client.received.end.timestamp)}</Template> </AssignVariable> <Set> <Payload contentType='text/plain'>error at {formattedTime}</Payload> <StatusCode>400</StatusCode> <ReasonPhrase>Bad Request</ReasonPhrase> </Set> </FaultResponse> </RaiseFault>
Thankyou for the trick.
ref:
https://docs.oracle.com/javase/8/docs/api/java/text/SimpleDateFormat.html