The first thing I notice is that you are using message templates. Such a useful feature in Apigee. But I think you may be misunderstanding how these curly braces work. The names wrapped in curly braces, like {literal_value} and {client.ip} and {request.content}, all get replaced, at runtime, with the values of the context variables by those names.
Normally the curly braces in a message template are used on the RIGHT HAND SIDE of values in a JSON hash. Using something like this:
{
"foo" : "{literal_value}"
}
…as a message template, when evaluated in a context in which the context variable literal_value holds 42 , will result in a JSON of
{
"foo" : "42"
}
And of course you can have as many of those curly-braced words as you like, within a single template. In your case you are doing something unusual. You are using variable replacement on the LEFT HAND SIDE, that is to say, you are using dynamically-determined key names in the template, as well as dynamically determined values on the RIGHT HAND SIDE. Like this:
{
"{literal_value}" : "{Hi! I am a literal value}"
...
}
So if literal_value holds the value 42 then you will get a JSON has with “42” as one of the property names. and the VALUE of that property will be… whatever is held in the context variable named “Hi! I am a literal value”. So, like this:
{
"42" : "whatever-was-stored-in-the-variable"
...
}
I am guessing, that Hi! I am a literal value is not really the name of a variable in your flow. That is why I think maybe you are misunderstanding how these curly braces work. I am guessing that you actually want something like this:
{
"literal_value" : "Hi I am a literal value",
"variable1" : "{client.ip}",
"request" : ... ,
"response" : ...
...
}
Where the key NAMES (literal_Value, variable1, request, response… the things appearing to the LEFT of the colons) are fixed, static, and known at configuration time, and the VALUES (to the RIGHT of the colons) are potentially dynamic, determined at runtime.
OK that’s item #1.
The second thing I notice is that you are using {request.content} and {response.content} in the right hand side. Those are valid references to context variables, and I think I understand what you are aiming at there. BUT, in general that won’t work, because the message template in Apigee is doing straight string replacement. To give an example of why this is important, let’s suppose the template is like this:
{
"foo" : "{literal value}"
}
We know that if the literal_value context variable holds 42, then the result is
{
"foo" : "42"
}
What happens if the literal_value holds the value Quoth the Raven “Nevermore.” ? The message template does string replacement, which means you get
{
"foo" : "Quoth the Raven "Nevermore.""
}
It might be non-obvious, but that is not valid JSON. If formatted differently, it is like this:
{
"foo" : "Quoth the Raven "
Nevermore.""
}
It starts off, ok, the “foo” value is "Quoth the Raven " (with a trailing space). But there is no comma after the end quote there, and the next token is a bare string (not quoted) Nevermore, which is not valid JSON. JSON keys must be quoted.
Anyway the point is , with straight string replacement, if the context variable contains double quotes, then you will not get valid JSON. Typically this problem shows up when people embed a variable that itself contains JSON. That will almost always produce invalid JSON. For example, imagine the request content is:
{ "id" : "u8378aq" }
And the mesage template is:
{
"request" : "{request.content}"
}
The result of evaluating the template is:
{
"request" : "{ "id" : "u8378aq" }"
}
Again, not valid JSON. With different whitespace, it’s easier to see:
{
"request" : "{ "
id" : "u8378aq" }"
}
Here again, it starts out ok, but there is no traliing comma after "{ " , and the next token is a bare id followed by an open quote.. . It’s not JSON.
I suspect you are sending something like that, something that kiinda looks like JSON but definitely is not json, to the cloud logging system. And that system is saying “ok, I don’t know what you just sent me, but it’s not json, and I’m not logging anything.”
Too much explanation, maybe. Really you just want to know the solution. Here it is: JSON escape the values on the right hand side. This is required if the values might contain quotes, like Quoth the Raven "Nevermore." or { "id" : "u8378aq" }. To do that, use this syntax for your template:
{
"request" : "{escapeJSON(request.content)}",
"response" : "{escapeJSON(response.content)}",
...
}
When you do that, the result of the template is like this:
{
"request" : "{ \"id\" : \"u8378aq\" }"
}
…which is valid json. This escapeJSON function is described in the documentation for message templates.