How do I make ansible-playbook log its output in a machine readable format like xml or json?
This is done using one of the configuration options. For a general overview of configuring Ansible, see the configuration documentation, in particular the callback plugin configuration.
Callback plugins change how Ansible provides feedback on the progress and state of tasks. There are several options for JSON output:

JSON output to stdout
JSON to syslog

Setting these configuration options can be done either in a configuration file (ansible.cfg) or with environment variables (ANSIBLE_XXX), depending on what you prefer.
To quote the current documentation:

Changes can be made and used in a configuration file which will be searched for in the following order:


   ANSIBLE_CONFIG (environment variable if set)
   ansible.cfg (in the current directory)
   ~/.ansible.cfg (in the home directory)
   /etc/ansible/ansible.cfg



Ansible will process the above list and use the first file found, all others are ignored.

Assuming you want to send the output to stdout then, your ansible.cfg could look like:
[defaults]
callback_whitelist=json
stdout_callback=json

Using environment variables:
 ANSIBLE_CALLBACK_WHITELIST=json ANSIBLE_STDOUT_CALLBACK=json ansible-playbook ...