Reputation: 77127
Log messages from an application conform to LogStash expectations (JSON), but we haven't got LogStash up and running in every case, so I've been trying to learn to use jq to read output when LogStash isn't available. The problem becomes tricky when the output is XML within the JSON. I get output like…
{
<SNIP>
"rom_response_body": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<OrderCreateResponse xmlns=\"http://api.example.com/schema/checkout/1.0\">\n <ResponseStatus>Success</ResponseStatus>\n <ResponseDescription>CustomerOrderId = 0005410600539 , OrderUUID = 57c27a87-2f2e-41d1-bc20-afef511b91aa</ResponseDescription>\n</OrderCreateResponse>",
<SNIP>
}
What I would like to get is:
<?xml version="1.0" encoding="UTF-8"?>
<OrderCreateResponse xmlns="http://api.example.com/schema/checkout/1.0">
<ResponseStatus>Success</ResponseStatus>
<ResponseDescription>CustomerOrderId = 0005410600541 , OrderUUID = 3bc76558-f5aa-4e2e-866d-5c4707e873db</ResponseDescription>
</OrderCreateResponse>
Or at least the well-formed xml in any raw form (from that point I can use xmllint). And I can sorta get there with jq. If I do
tail system.log | jq "select(.rom_response_body)|.rom_response_body|fromjson"
I get error output like
jq: error: Invalid numeric literal at line 1, column 6 (while parsing '<?xml version="1.0" encoding="UTF-8"?>
<OrderCreateResponse xmlns="http://api.example.com/schema/checkout/1.0">
<ResponseStatus>Success</ResponseStatus>
<ResponseDescription>CustomerOrderId = 0005410600541 , OrderUUID = 3bc76558-f5aa-4e2e-866d-5c4707e873db</ResponseDescription>
</OrderCreateResponse>')
I think the problem is that that input is not actually json, it's just a json-escaped string literal. It would be valid if wrapped with {"key": }
. Is there a saner way to get the output I need besides manually wrapping each line to make it complete JSON?
Upvotes: 1
Views: 1912
Reputation: 134881
The default output format is one or more valid JSON values. XML is clearly not JSON. However the string itself is valid, but the value it represents isn't. You can ignore this restriction by using the raw output option (-r
). This will return the value of the string.
$ tail system.log | jq -r '.rom_response_body'
<?xml version="1.0" encoding="UTF-8"?>
<OrderCreateResponse xmlns="http://api.example.com/schema/checkout/1.0">
<ResponseStatus>Success</ResponseStatus>
<ResponseDescription>CustomerOrderId = 0005410600539 , OrderUUID = 57c27a87-2f2e-41d1-bc20-afef511b91aa</ResponseDescription>
</OrderCreateResponse>
Upvotes: 2